#Arduino Help

1 messages · Page 8 of 1

coral geyser
#

Sorry, i am having a hard time parsing your questions

wary cloak
#

I just that I can't get it because the behavior

#

It's totally different now

coral geyser
#

this message broke my brain 🧠

wary cloak
#

Before:
Low: nothing, for no short circuit
High: 0, to match the other 0 when a input is pressed because it's default it's 5 volts

Now:
Low: 0 volts (which before was our high)

High: 5 volts but not at all

#

We need a cero and another cero for a key pressed but now cero is not column high but low

#

Is inverted

coral geyser
#

it wants to be like 4.5v but it doesn't have much force to keep it there

#

the 0v output can drive it to 0v without much current flowing

wary cloak
#

That's what I can't understand

#

So you are saying

#

That high would be almost 5 volts first but then it will drop to 0?

#

Hence behaving like before?

coral geyser
#

I would need to get into electronic theory to explain better

coral geyser
#

close enough to that for our purposes

wary cloak
#

I'm ashamed to be a close to technician in electronics and having this difficulties -

#

Ok so let's say high is 0 like before

coral geyser
wary cloak
#

But what about low, isn't it 0 also? You answered it was an absolute 0, but why is it an absolute 0 and not plain 0,and what's the difference?

#

Hard 0*

wary cloak
#

My question are:
-what's a hard 0, and why it's different from a normal 0 volt?
-why when low is our pin a hard 0 and not just 0?
-why high goes down to 0 volt? (Or close enough)
-how do we avoid short circuit? (Tho maybe by understanding the above this isn't necessary)

coral geyser
#

(This is miss labeled, tine internal pull up resistance, should be huge ...)

#

I tried

#

I don't have a circuit drawing app on this computer

wary cloak
#

Well I need to go to sleep like 2 hours ago so I need to leave

wary cloak
#

About tomorrow

#

We can finish understanding that

#

Having rested

#

And about code well

#

Next step it's to make lcd and keyboard work together which I hope should be as easy as, kill read_char function and replace where it was called with wait_for_key

#

I really hope that's all

#

And then depending on what was choosen as the intensity toggle the pins of the relay modules a certain delay it should take like 10 minutes

#

And finally..

#

The base functionality of the project

#

Would be done

#

Anyways tomorrow we do that and understand this

#

It's that four questions I sended basically

#

Good night and thanks for the support

coral geyser
coral geyser
coral geyser
coral geyser
#

In the figure for 3. the current is small because it goes through a large resistor first

#

the circuit for the ouput/input connected looks like

wary cloak
#

@coral geyser are you available?

hallow hinge
#

Hi. :)

#

@wary cloak I'm glad this seems to be working out for you. I also do embedded stuff. Feel free to ping me in case.

wary cloak
hallow hinge
#

🥳

wary cloak
#

@hallow hinge @coral geyser are you available?

hallow hinge
#

Ji

#

I am n0w

wary cloak
#

Oh I was checking something from the C++ version of this project see if I finally make something work

#

After we can continue getting rusty

#

Today's objective is finally finishing the base functionality of the project

coral geyser
#

I am on/off I will be working extra for the rest of the afternoon

wary cloak
#

Wdym on/off(?

coral geyser
#

I am on my own time, so can answer questions, but I won't have discord open all the time so may miss pings

wary cloak
#

Oh ok

#

So you are here but more or less it depends

#

Well today's objective should be fairly easy I suppose

coral geyser
#

Yeah, I have a few hundred lines of code to write today

wary cloak
#

First we should merge the lcd and keypad I hope the only thing I would have to do is get out read char and replace it with wait_for_key and that's it

#

That should be it -

coral geyser
#

Yeah, should be

wary cloak
#

Tho the thing is were we instanciate our keypad "object"

#

Because it will be used in the status machine

#

Any clue where?

#

And also..

#

What should I call this new project?

#

Because it ain't it's final form

#

But only the one without rfid

#

Simple bartender maybe

#

Oh I'm having dinner

#

Brb

#

Tho soon after I come back I'm having my class about github we will see how we manage it-

wary cloak
#

I'm back

#

@coral geyser @hallow hinge are of you two here?

hallow hinge
#

Yep

#

Well

#

I don't know about them

#

But I'm here lol

wary cloak
#

I got confused for a fraction of a second

#

Well

#

A small question

#

Have you by chance read what we were working on?

hallow hinge
#

Not really, the backlog here is like veerryyy large lol

wary cloak
#

Ofc because I'm in it(?

hallow hinge
#

It's a bit impossible to check because Discord doesn't index threads.

#

Though

#

Can you give me a summary? :)

wary cloak
#

Well it would be nice if I could find the message explaining what is the project and then I could say and we did this already

#

Well the search words is for the whole server and not just this thread that's trouble some ferrisHmm

hallow hinge
#

Yeah, it's annoying. You can at least do in:#rust-help

#

But there's no way to check for this specific thread

wary cloak
#

At the beginning?

#

Or at the end?

hallow hinge
#

It doesn't matter. This is what I'm using as a search query rn

#

from: λ Azazel#5874 RFID in: rust-help

wary cloak
#

That maybe isn't helping much because I write a lot(?

hallow hinge
#

You mention this tho .

#

.

#

And a bunch of code here .

wary cloak
#

Oh they are calling me to clean the plates

#

Brb again

#

Tho my class starts soon but

#

Maybe I will be able to give insight at least

hallow hinge
#

Okay. :3 Just @ me when you start talking, because I mostly just check if #offtopic has activity before tabbing to another Discord lol

wary cloak
#

Sure

wary cloak
#

@hallow hinge I'll be busy for the next two hour because of my class but I may have a break

#

I'm making an automatic bartender

hallow hinge
#

Oh, sounds fun. 👀

#

Also, what microcontroller are you using?

wary cloak
#

First I'll explain the base functionality of the project which I what we are about to finish

hallow hinge
#

Arduino Mega? The AVR one?

#

embedded_hal works with that?

wary cloak
wary cloak
hallow hinge
#

TIL

wary cloak
#

Also it's a school project

hallow hinge
#

I'm glad to hear that though. :)

wary cloak
#

Because in this last year we have a subject for that

hallow hinge
#

Can you show me your Cargo.toml btw?

wary cloak
#

I'm in my last year or secondary school to be a technician in electronics

#

Which one

#

Well I guess

#

They were equal in both projects more or less

#

Just that I had to add an lcd dependency for the other

#

My computer is slow

#
[package]
name = "keypad"
version = "0.1.0"
authors = []
edition = "2021"
license = "MIT OR Apache-2.0"

[[bin]]
name = "keypad"
test = false
bench = false

[dependencies]
panic-halt = "0.2.0"
ufmt = "0.1.0"
nb = "0.1.2"
embedded-hal = "0.2.3"

[dependencies.arduino-hal]
path = "avr-hal/arduino-hal"
features = ["arduino-mega2560"]

# Configure the build for minimal size - AVRs have very little program memory
[profile.dev]
panic = "abort"
lto = true
opt-level = "s"

[profile.release]
panic = "abort"
codegen-units = 1
debug = true
lto = true
opt-level = "s"
hallow hinge
#

I get how you feel lol. It's been like half a decade though, huh. I used to have a 2003 computer as my daily driver.

#

Thanks. :)

wary cloak
#

And there's also .cargo

#

As you'll notice this is for the keypad project

#

Tho it has one key difference is that we are using Arduino hal locally because of something we had to change from it because Arduino Mega is a special boy

#
[build]
target = "avr-specs/avr-atmega2560.json"

[target.'cfg(target_arch = "avr")']
runner = "ravedude mega2560 -b 57600"

[unstable]
build-std = ["core"]
#

This is .cargo

hallow hinge
#

Thanks. :) That's so cool.

#

Also, you can try opt-level = "z" if you need even more PROM.

wary cloak
#

We could try but for now works decent

wary cloak
#

It's an automatic bartender and it would be like this

#

First we turn it on

#

The users sees in the lcd

#

Which drink you want?

#

And three options

#

If he presses whatever

#

It will say that, that's an unvalid key

#

Invalid*

#

And go back

#

If you press option 2 and 3

#

It will say drink not available because at least for now it's made to work in one case tho we could easily expand it

#

And ofc go back

#

So you can only select drink 1

#

Idk about alcoholic drinks so names are temptative

#

With the matricial keyboard the users gives the comand

#

And we go to the next screen

#

How intense you want it?

#

Hard, medium, soft

wary cloak
#

When you chose intensity

#

A waiting message would be displayed on screen

#

Preparing..

#

With a blinking cursor

#

And we would active relay modules

#

To open... "Electrovalvulas" (Idk how to say it in English)

#

So the liquid in that bottle or recipient

#

Will fall to the glass

#

Then the next

#

And the delay depends on the intensity the order of activition is always the same

#

We had the lcd and keyboard working

#

Today we should make the lcd and keyboard work together

#

So we don't need to use serial

#

And do the logic for depending the choice of intensity how many times each relay is high

#

That's the two parts of what I was planning today ofc

hallow hinge
#

Cool. :) Can you reply to the part which you've already done?

wary cloak
#

One issue aside from that it works on one case only

#

Is that the times are by calculation "lazo abierto"it's not sensed so.. It'll be a deal

wary cloak
#

Lcd and keyboard by their own done

#

Today lcd+keyboard together and relay logic

#

My class just started so if I disappear you know

hallow hinge
#

Thanks. This seems fun. :)

wary cloak
#

Any other question about what we are doing or need to do or has been done or whatever maybe?

hallow hinge
#

I'll enable all notifications here lol so that I get notified when people message here even without @ing.

wary cloak
#

The last thing would be explaining what will be the final project, this is base functionality

#

Oh I forgot one other thing aside that

#

And is why I'm re writting this project and the fact that I'm re writting it

hallow hinge
#

Everything seems to make sense to me. :) But yeah, would have to see your actual code to judge.

wary cloak
#

I could send what has been done as a zip if you wanted to(?

hallow hinge
#

Sure thing.

wary cloak
#

Sure after the class I'll do it

#

And also explain why re writting in rust and what the end goal is

hallow hinge
#

ferristhumbsup excited to see all of it

wary cloak
#

Well this project is ofc originally done in Arduino IDE (C++) I got stuck, I sometimes struggle to advance, hate compile error messages in Chinese, and I really depend on a programmer friend I know that now is not active to advance because he is good at programming and can help a lot even tho he barely knows C and nothing of embedded, thing is, I learned rust which I became really excited about, I wanted to use it in practice, become a real good true rust programmer, maybe being able to be more independent or less insecure about trying to code and also less afraid of errors, and maybe with rust I wouldn't get stuck, and also I would like to be able to do what little I know to do in C++ also in rust so I could keep going in rust, give it usage, and as a low level systems programming doing embedded with it makes sense and I love embedded, tho it's an expensive hobby and economy here is one of the worst of the world so likely I won't be able to do much more embedded until I have my desired programmer money(?

#

Tho I see that the ecosystem for embedded rust I really inmature and stuff so I guess I would have to stick with the gigantic C++ ecosystem- but I wanna finish doing this at me at a this project, learn how to, I wanted to know how to program Arduino in rust (later raspberry Pi pico, I'm buying it soon)

#

Well more or less that's the deal ig

#

Good that I want to try out web development and for any reason a low level programming has a way bigger ecosystem for web dev than embedded (?

hallow hinge
#

Yeah. Though, personally, I find that the Rust libraries, while relatively sparse, are of better quality than the C++ counterparts. Also, it's much easier to modify them.

wary cloak
#

Problem is there aren't sometimes, the struggle we went through for the keyboard

#

When in Arduino was

#

Install library

#

Little setup to instanciate the object

#

Done

#

Here well because of the weird open drain behavior we had all this issues

#

Also the serial monitor works really bad

#

It's too inmature

#

Which is a shame because I really want to use rust for everything and get use to it

#

So I hope I love web dev and also rust there

#

Anyways more or less that's the thing tho

#

I'm still working on the Arduino version

#

But I can't on my own so I'm stuck

#

Which sucks because I'm so close to finish-

hallow hinge
#

:(

#

I'd help, but I'm unfamiliar with C++ lol

wary cloak
#

Think you could maybe help with that on&

#

Yeah me neither

#

That's a thing

#

I don't know C++

#

I actually really learned programming and got into this world like..

#

4 months ago or so

#

And this is like my first project-

hallow hinge
#

Ah. :(

#

Guessing you had to learn it for this class?

wary cloak
#

No, thing is pandemic (?

#

In a normal scenario

#

I would 'be learn decently well C

#

Some C++

#

And done some projects in Arduino small ofc in comparison

#

But for example I would have known how to do lcd and matricial keyboard work already and stuff

#

And since I would likely had love it

#

Alternate me

#

Has already 2 years of programming experience and can likely do all this by it's own at learn Arduino version

#

I may go in insight over that after my class because I can't concentrate now

#

But for this year we are suppose to have technically two years of experience and now C, to some extent C++ and have Arduino experience

#

So it should be doable or at least we aren't clueless like

#

What's programming?

#

I just was so unlucky

hallow hinge
#

Ahhh :/ so basically, this should have been already be a part of your formal studies?

wary cloak
#

The two most important years of the career more or less

#

I should be a big ballsy programmer by now km

#

(? *

#

But I'm a newby

#

And most importantly

#

I don't know a thing about Cpp

#

Which to understand the rfid hell

#

Would've been careful

#

Helpful*

hallow hinge
#

Oh yeah, actually. How does RFID relate to your project? You didn't mention it a while ago

wary cloak
#

Until rfid I did the whole thing in a week, then rfid came and a month and so

hallow hinge
#

(Or are you learning that for a separate project?)

old mango
hallow hinge
hallow hinge
wary cloak
#

Pandemic not only fucked me up with programming but also electronics ofc so I surely don't know so many things I should and it's a shame because I ain't seeing it again and it was really interesting or maybe I would have love it and follow it but know I wouldn't know

#

I could've been really good at electronics and I would've been so proud -

#

And it would also help a lot with my embedded career say or knowledge or programming or whatever

#

Anyways I'm compressing the two already done projects

#

So you can get a look

#

Ok there should be the keypad program

#

Wait a little bit for the second one(?

#

Which would actually be the first done but whatever

#

Oh no-

#

It says it's too heavy :(

#

That's annoying

#

Because basically what we are going to do is add those two codes and then write on top

#

So you having the bases would be useful

#

Understanding how everything works and being up to date

hallow hinge
#

Also hmm

#

I think it's because you're zipping your target directory with it.

wary cloak
#

Ah yes

#

I'm in class and my computer it's slow I can't do much

#

I forgot about it

#

So sorry but the keypad one has the target folder -

#

I hope that isn't annoying

#

Tell me when you have seen it and if you have any doubts with the code or how it works

#

We just worked on it so scrolling up you could see something interesting but ofc lcd is much up there

#

The lcd code was easier to make work but we made like overkill and made a state machine and all

#

So it's really clean

old mango
#

?? Seen what

wary cloak
#

I just said that if there's any issues with understanding the keyboard it could scroll a little up to see when we did that and why

#

Tho ofc I would answer questions in any case

old mango
#

I'm not sure what you're looking for here?

wary cloak
#

WOW

#

IS TARGET THAT HEAVY?

#

It went from

#

Like 100 mb

#

To kb order

#

Wow..

old mango
#

Yeah, it's a lot of stuff

wary cloak
#

@hallow hinge ok now you can check both codes and that's mostly it the only thing left would be to explain you the end project

#

But that's not necessary for today's objective

#

But yes for tomorrow's in case today we do what I expected

#

Oh there's also another small detail

wary cloak
#

I only have that subject on Wednesdays so tomorrow

#

So what I care about the most

#

Is completing a goal for Wednesday

#

And then there's a whole week to work with

wary cloak
#

Any questions feel free

wary cloak
#

Ok I'm finished

#

So

#

If you are ready there's one last thing I want to tell you and we can start working

#

With that basically like there's not more context to be given

hallow hinge
#

Sure thing. I'm still currently reading it.

wary cloak
#

Well basically the end project

#

After this my professor said

#

Hey wouldn't it be cool if it had a payment system

#

And an Innocent me said yes it would be

#

So I bought the MFRC522 I think it was called

#

For read/write data

#

The first code was the one who read the data from the rfid and printed it our

#

Out*

#

Then

#

A code to change the password of one sector

#

To be safe and it's important to know

#

But what happened

#

The base code for reading works only with a base just bought card with the default password that all have

#

So go into the fit repository of the library

#

And create more or less our own function

#

So it can read with the password I want

#

Small detail

#

All sectors should have the same password

#

So

#

Create a new code on top of the other one

#

To change passwords for all sectors

#

Now that we can change the password of our card and read the data in it

#

The next step was the prototype of the functionality so knowing how to do it I later add it to the base functionality of the project

#

Normally we would have one device to charge money and another to buy from bit for economics and scope reason this one do both of them.

#

So

#

What would the project be like now?

#

Well first the lcd will display

#

Do you want to

#

Buy? Charge money? Or see how much money you got?

#

If you say buy

#

Everything it's like always

#

But now when you choose a drink

#

You have to put the card so it discounts you the money and let's you move on

#

Or after the intensity actually

#

It checks if you have enough

#

If not it says, not enough money and sends you back to the beginning

#

If not well that money is consumed

#

If you chose to check how much many you got

#

You put the card in the reader

#

And it shows you in decimal numbers how much money you got

#

And then goes back

#

Finally you can say I wanna charge money

#

So you do

#

And then it says

#

How much?

#

And with the matricial keyboard you type the number

#

Then get the card on the reader

#

It's charge and it goes back to the beginning

#

I already made this work in Arduino the prototype

#

That's base rfid the payment system

#

Ofc this all works with my card only because I changed it's password

#

But my teacher told me to add another functionality which is where I'm stuck now

#

He said it would be a pain to manually change the passwords of all cards to be usable for my project

#

We discussed different ways of doing this so I'm going to tell you the one I'm doing

#

There's another starting menu.

#

Do you want normal mode or master mode?

#

Normal mode, do what you always did

#

Master mode, you can get your new bought card to the reader and it will change it's password so easy and fast you can know use also that card in my machine

#

But ofc

#

Not anyone can enter

#

First time it turns one (yes I will have to know it's the first time)

#

It will ask you via matricial keyboard to type in a password

#

So know that password will be stored in the EEPROM and you can enter master mode with said password

#

Also you can change your password using ofc the one you already have

#

But if you forget

#

There should be a master password in the EEPROM that only technician will now about to fix your problem

#

Phew

#

Ah and also

#

This is my add but

#

I want that when you get a card that can already be use it prints

#

This card it's already on the system

#

And goes back

#

Also you can as many as you want then press something and go back

#

That's all the rfid stuff

#

Now there's one last thing to the project but it's way easier

#

We will have an "infrarrojo" Sensor to check if there's a glass or not

#

If there's not it won't server

#

And also ultrasonic sensors on top of the recipients

#

To check the distance between the top and the liquid

#

When there's no more liquid

#

It will ask you to fill it and it won't work

#

It has to be fool proof

#

So that's the final goal

#

Any questions?

hallow hinge
#

No questions rn. : P

#

But will have to give a second pass on reading

wary cloak
#

Sure, the good thing is

#

Up until now I finished doing something and there was more

#

But now there's a confirmed finished condition which are the sensors

#

That's sooo good

#

Any doubts on the code?

hallow hinge
#

Still also reading it. :P

wary cloak
#

I'm preparing the new project

hallow hinge
#

Will probably give you some thoughts in like ~8 hours maybe? Since will have to work in a bit.

wary cloak
#

Shamefully I can't stay awake this much (or shouldn't) but tomorrow's Wednesday and I test in the actual built stuff like real scenario not only components the base functionality of the Arduino project I want to take the opportunity to test rust as well and show the rest writting is viable

wary cloak
#

Also..

#

@coral geyser are you here now? Because now I can finally start working

#

Well I created the new project I merged both mains, for now I copied all the module, I copied the Avr specs, .cargo, avr-hal, the toml from keypad and only added the lcd dependency now I'm going to run cargo build

#

To have an idea of what is like

#

well in the meantime

#

We have an issue

#

Ofc to call wait for key

#

We need to have instanciated our strict

#

Struct*

#

But it doesn't make sense to instanciate it there but idk how I would pass it, does my status struct take ownership of it?

coral geyser
#

Put it in the Bartender struct ferrisGlasses

wary cloak
#

So it would be

#
pub struct Bartender<Serial> {
    state: State,
    selected_drink: Option<Drink>,
    selected_intensity: Option<Intensity>,
    lcd: Display<LcdConnection>,
    serial: Serial,
    keypad: Keypad,
}
#

Right? And I leave the declaration in main

#

Also soon we are getting rid of the serial struct and it's declaration of mean I suppose and also that requirement in function parameters and impl block and so

#

Well that it's going to be a little bit of a mess

#

But anyways, so far so good?

coral geyser
wary cloak
#

And new would look like

#
impl<Serial> Bartender<Serial> where Serial: Read<u8> + Write<u8> {
    pub fn new(lcd: Display<LcdConnection>, serial: Serial, keypad: Keypad) -> Self {
        Self {
            state: State::SelectDrink,
            selected_drink: None,
            selected_intensity: None,
            lcd,
            serial,
            keypad,
        }
    }
#

Ofc until removing serial

#

Ok so I think I will just do it

#

And tell you when something bad happena

#

Happens*

#

?

#

Idk why I always have scope issues-

#

It's infuriating-

#

Ok I got rid of all the serial stuff so

#

How do I fix that error?

#

I think it's that and.. We could test it

#

I hope it isn't annoying I just ping you again just in case because you said you wouldn't receive all notifications or smth like that @coral geyser

#

I use a use statement to all the module, the struct own keypad, wait for key is public, what else does it want for me how the hell isn't it in scope -

#

owns*

coral geyser
wary cloak
#

It could be(?

#

Let me see

#

The self it's the same? Parameter I mean

coral geyser
#

Keypad::wait_for_key(...) Is the long form

coral geyser
wary cloak
#

Doesn't it need self-?

coral geyser
wary cloak
#

Ok cargo check now because I see no errors

#

It compiled

#

Excellent

#

Let's test it

#

If it works we have no much left to do :')

coral geyser
#

?eval ```rust
#[derive(Debug)]
struct A;

impl A {
fn test(&self) {
dbg!(self);
}
}

let x = A;
x.test();

robust mountainBOT
#
     Running `target/debug/playground`
[src/main.rs:7] self = A

()
wary cloak
#

It's the moment of truth..

#

You ready?

coral geyser
#

No

wary cloak
#

Delay's too long

#

But it seems to be working

#

It completely woooorks

#

Ok now let's talk about the last thing

#

Now

#

We need to get the relays part

#

Basically

#

When you choose intensity and while " preparing.. "

#

Is showing

#

You start sending highs to the relays

#

One at a time

#

Same order

#

The code it's the same for each case

#

Only thing that changes it's the delay

#

So I will show you

#

How I did the code first time the messy manual repetitive way

#

And then how I did a function for it

#

We adapt it to rust and

#

That's it

#

No library no nothing

#

Just togglin 4 pins a certain delay

#

On here I look for them show them to you and we do it and.. That would be it for today

#
switch(tecla){
      case '1':
      digitalWrite(4,HIGH);
      delay(2000);
      digitalWrite(4,LOW);
      delay(1000);
      digitalWrite(3,HIGH);
      delay(4000);
      digitalWrite(3,LOW);
      delay(1000);
      digitalWrite(2,HIGH);
      delay(4000);
      digitalWrite(2,LOW);
      delay(1000);
      break;
      case '2':
      digitalWrite(4,HIGH);
      delay(3000);
      digitalWrite(4,LOW);
      delay(1000);
      digitalWrite(3,HIGH);
      delay(3000);
      digitalWrite(3,LOW);
      delay(1000);
      digitalWrite(2,HIGH);
      delay(3000);
      digitalWrite(2,LOW);
      delay(1000);
      break;
      case '3':
      digitalWrite(4,HIGH);
      delay(6000);
      digitalWrite(4,LOW);
      delay(1000);
      digitalWrite(3,HIGH);
      delay(2000);
      digitalWrite(3,LOW);
      delay(1000);
      digitalWrite(2,HIGH);
      delay(2000);
      digitalWrite(2,LOW);
      delay(1000);
      break;
      
    }
  }
#

This is the repetitive way

#

Tho in this version I only toggled three pins now they are four

#

Now

#

This is the function I made

#
void Barman (int delay_alchohol, int delay_acompanante1 , int delay_acompanante2, int delay_acompanante3){
      digitalWrite(PIN_ALCHOHOL,HIGH);
      delay(delay_alchohol);
      digitalWrite(PIN_ALCHOHOL,LOW);
      delay(1000);
      digitalWrite(PIN_ACOMPANANTE1,HIGH);
      delay(delay_acompanante1);
      digitalWrite(PIN_ACOMPANANTE1,LOW);
      delay(1000);
      digitalWrite(PIN_ACOMPANANTE2,HIGH);
      delay(delay_acompanante2);
      digitalWrite(PIN_ACOMPANANTE2,LOW);
      delay(1000);
      digitalWrite(PIN_ACOMPANANTE3,HIGH);
      delay(delay_acompanante3);
      digitalWrite(PIN_ACOMPANANTE3,LOW);
      delay(1000);
}
#

and this the implementation

int delay_alchohol;
    int delay_acompanante1;
    int delay_acompanante2;
    int delay_acompanante3;

    switch(tecla){
      case '1':{
      delay_alchohol = 2000;
      delay_acompanante1 = 4000;
      delay_acompanante2 = 4000;
      delay_acompanante3 = 4000;
      Barman (delay_alchohol, delay_acompanante1, delay_acompanante2, delay_acompanante3);
      break;
      }
      case '2':{
      delay_alchohol = 5000;
      delay_acompanante1 = 3000;
      delay_acompanante2 = 3000;
      delay_acompanante3 = 3000;
      Barman (delay_alchohol, delay_acompanante1, delay_acompanante2, delay_acompanante3);
      break;
      }
      case '3':
      {
      delay_alchohol = 8000;
      delay_acompanante1 = 2000;
      delay_acompanante2 = 2000;
      delay_acompanante3 = 2000;
      Barman (delay_alchohol, delay_acompanante1, delay_acompanante2, delay_acompanante3);
      break;
      }
    }
  }
#

So.. How do we start? Another module, or a method of the bartender struct?

coral geyser
wary cloak
#

Ok so I will do it below do show waiting screen

#

How do we call it?

#

And also, a public function? Or a private one

#

I mean

#

Update will take care or this too?

wary cloak
#

Well so that, will it be public or will it be private?

#

Tho thing is this.

#

It will be serving the drink and while it's doing it

#

It will be displaying the waiting message

#

That means it's status will still be waiting so..

#

In the update signature

#

Do I add brackets to the match state waiting first call do show waiting screen and then serve_drinks?

#

And also.. So I remove the state change to serve drinks?

#

Because you know if that's the case we could directly call waiting screen in the update function because do show waiting screen called waiting screen and changed state so..

#

I will tell you my idea

#

So..

#

We get rid of do show waiting screen

#

Then in the match expression we add brackets to the waiting screen state

#

First we call show waiting screen

#

Then we call serve drinks

#

So the function is private

#

And inside serve drinka

#

Drinks *

#

We will change the state back to select drinks

#

Do you agree with that?

#

And if you do the thing is how do we implement the function, do we have to declare in main aside from the pins, 4 variables representing each delay initialized as 0?

#

Will our struct take owner ship of the pins it needs to toggle?

#

I have so many questions-

#

Because then pins would need to be an array but then delays too

#

So..

wary cloak
#

Btw @coral geyser should I ping you for questions or let you be and wait? Because I have notifications off and I really don't know how annoying it could be or that

coral geyser
coral geyser
wary cloak
#

It won't be at runtime

wary cloak
#

As you see in the code I showed you I enter a switch that sets the delays for each case instead of high low high low each time basically

coral geyser
wary cloak
#

Well yeah the idea was depending on the intensity selected we could check the enuma

#

Only delay changes

#

Not the pins not the order

#

Just the delay

coral geyser
wary cloak
#

But first of all

#

Do you agree with my idea?

#

Of getting rid of

#

Do show waiting screen

#

In update call waiting screen and then serve drink and serve drink would change states

coral geyser
#

Sure sounds reasonable

wary cloak
#

Now, why doesn't it work?

#

I tried without .lcd also

#

And it says that

coral geyser
#

Is it pub?

wary cloak
#

It is

#

and I have another important question after this one regarding the pins but ofc this first

#

but basically how do i declare the pins an add them to the struct?

#

btw the pins are 6,4,3,2

#

and are activated in that order

wary cloak
#

so.. I did the following

#

in main this

#
let pins = [
        pins.d2.into_output().downgrade(),
        pins.d3.into_output().downgrade(),
        pins.d4.into_output().downgrade(),
        pins.d6.into_output().downgrade(),
    ];

    let mut bartender = Bartender::new(lcd, keypad, pins);
#

in the struct definition this

#
pub struct Bartender {
    state: State,
    selected_drink: Option<Drink>,
    selected_intensity: Option<Intensity>,
    lcd: Display<LcdConnection>,
    keypad: Keypad,
    pins: RelayPins,
}

type RelayPins = [Pin<Output, Dynamic>; 4];
#

ofc adding the use statements needed

#

and in new this

#
impl Bartender {
    pub fn new(lcd: Display<LcdConnection>, keypad: Keypad, pins: RelayPins) -> Self {
        Self {
            state: State::SelectDrink,
            selected_drink: None,
            selected_intensity: None,
            lcd,
            keypad,
            pins,
        }
    }
#

@coral geyser did I do all the pins deal right?

#

Since my program is sending the 1 and so well it should be output and you know why dynamic

#

well i will go to sleep i hope maybe we can work it out before i go or smth idk in any case

#

i will leave what else i did

#

so

#

the update functions is this now

#
pub fn update(&mut self) {
        match self.state {
            State::SelectDrink => self.do_show_drinks(),
            State::SelectIntensity => self.do_show_intensity(),
            State::Waiting => {
                self.show_waiting_screen(&mut self.lcd);
                self.serve_drinks(&mut self, pins);
            }
        }
    }
#

and i did the function serve drinks or at least most of it

#
fn serve_drinks(&mut self, self.pins:RelayPins) {
        match self.selected_intensity {
            Intensity::Strong => {
                pins[0].toggle();
                arduino_hal::delay_ms(8000);
                pins[0].toggle();
                arduino_hal::delay_ms(1000);
                pins[1].toggle();
                arduino_hal::delay_ms(2000);
                pins[1].toggle();
                arduino_hal::delay_ms(1000);
                pins[2].toggle();
                arduino_hal::delay_ms(2000);
                pins[2].toggle();
                arduino_hal::delay_ms(1000);
                pins[3].toggle();
                arduino_hal::delay_ms(2000);
                pins[3].toggle();
                arduino_hal::delay_ms(1000);
#
}
            Intensity::Medium => {
                pins[0].toggle();
                arduino_hal::delay_ms(5000);
                pins[0].toggle();
                arduino_hal::delay_ms(1000);
                pins[1].toggle();
                arduino_hal::delay_ms(3000);
                pins[1].toggle();
                arduino_hal::delay_ms(1000);
                pins[2].toggle();
                arduino_hal::delay_ms(3000);
                pins[2].toggle();
                arduino_hal::delay_ms(1000);
                pins[3].toggle();
                arduino_hal::delay_ms(3000);
                pins[3].toggle();
                arduino_hal::delay_ms(1000);
            }
            Intensity::Weak => {
                pins[0].toggle();
                arduino_hal::delay_ms(2000);
                pins[0].toggle();
                arduino_hal::delay_ms(1000);
                pins[1].toggle();
                arduino_hal::delay_ms(4000);
                pins[1].toggle();
                arduino_hal::delay_ms(1000);
                pins[2].toggle();
                arduino_hal::delay_ms(4000);
                pins[2].toggle();
                arduino_hal::delay_ms(1000);
                pins[3].toggle();
                arduino_hal::delay_ms(4000);
                pins[3].toggle();
                arduino_hal::delay_ms(1000);
            }
        }
        self.state = State::SelectDrink;
    }
#

And finally, the errors

#

The one from before and idk why it says it expectes three arguments when they are clearly 2

#

And it says missing type but... It's clearly there

#

And finally I will show you the errors but via cargo check

#
Checking simple_bartender v0.1.0 (C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\simple_bartender)
error: unexpected `self` parameter in function
   --> src\state.rs:110:32
    |
110 |     fn serve_drinks(&mut self, self.pins:RelayPins) {
    |                                ^^^^ must be the first parameter of an associated function

error: expected one of `)`, `,`, or `:`, found `.`
   --> src\state.rs:110:36
    |
110 |     fn serve_drinks(&mut self, self.pins:RelayPins) {
    |                                    ^
    |                                    |
    |                                    expected one of `)`, `,`, or `:`
    |                                    help: missing `,`

error[E0415]: identifier `self` is bound more than once in this parameter list
   --> src\state.rs:110:32
    |
110 |     fn serve_drinks(&mut self, self.pins:RelayPins) {
    |                                ^^^^ used as parameter more than once

error[E0425]: cannot find value `pins` in this scope
  --> src\state.rs:57:46
   |
57 |                 self.serve_drinks(&mut self, pins);
   |                                              ^^^^ help: you might have meant to use the available field: `self.pins`

error[E0599]: no method named `show_waiting_screen` found for mutable reference `&mut state::Bartender` in the current scope
  --> src\state.rs:56:22
   |
56 |                 self.show_waiting_screen(&mut self.lcd);
   |                      ^^^^^^^^^^^^^^^^^^^ help: there is an associated function with a similar name: `do_show_waiting_screen`

Some errors have detailed explanations: E0415, E0425, E0599.
For more information about an error, try `rustc --explain E0415`.
error: could not compile `simple_bartender` due to 5 previous errors
#

Lok

#

I fixed all but one

#

In the end the function is like this

#
fn serve_drinks(&mut self, pins:RelayPins) {
        match self.selected_intensity {
            Some(Intensity::Strong) => {
                pins[0].toggle();
                arduino_hal::delay_ms(8000);
                pins[0].toggle();
                arduino_hal::delay_ms(1000);
                pins[1].toggle();
                arduino_hal::delay_ms(2000);
                pins[1].toggle();
                arduino_hal::delay_ms(1000);
                pins[2].toggle();
                arduino_hal::delay_ms(2000);
                pins[2].toggle();
                arduino_hal::delay_ms(1000);
                pins[3].toggle();
                arduino_hal::delay_ms(2000);
                pins[3].toggle();
                arduino_hal::delay_ms(1000);
            }
            Some(Intensity::Medium) => {
                pins[0].toggle();
                arduino_hal::delay_ms(5000);
                pins[0].toggle();
                arduino_hal::delay_ms(1000);
                pins[1].toggle();
                arduino_hal::delay_ms(3000);
                pins[1].toggle();
                arduino_hal::delay_ms(1000);
                pins[2].toggle();
                arduino_hal::delay_ms(3000);
                pins[2].toggle();
                arduino_hal::delay_ms(1000);
                pins[3].toggle();
                arduino_hal::delay_ms(3000);
                pins[3].toggle();
                arduino_hal::delay_ms(1000);
            }
#
Some(Intensity::Weak) => {
                pins[0].toggle();
                arduino_hal::delay_ms(2000);
                pins[0].toggle();
                arduino_hal::delay_ms(1000);
                pins[1].toggle();
                arduino_hal::delay_ms(4000);
                pins[1].toggle();
                arduino_hal::delay_ms(1000);
                pins[2].toggle();
                arduino_hal::delay_ms(4000);
                pins[2].toggle();
                arduino_hal::delay_ms(1000);
                pins[3].toggle();
                arduino_hal::delay_ms(4000);
                pins[3].toggle();
                arduino_hal::delay_ms(1000);
            }
            _ => {}
        }
        self.state = State::SelectDrink;
    }
#

Forgot selected intensity was optional, pins didn't need self, but yes when calling it but not another self parameter, I also didn't cover the none case

#

I also got rid of do show waiting screen

#

And I have that little annoying one error left

#
Checking simple_bartender v0.1.0 (C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\simple_bartender)
error[E0599]: no method named `show_waiting_screen` found for mutable reference `&mut state::Bartender` in the current scope
  --> src\state.rs:56:22
   |
56 |                 self.show_waiting_screen(&mut self.lcd);
   |                      ^^^^^^^^^^^^^^^^^^^ method not found in `&mut state::Bartender`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `simple_bartender` due to previous error
#

well say i solve it doing this

#
crate::lcd::show_waiting_screen(&mut self.lcd);```
#

tho I still do not know why here was necessary and not before but, as long as it works

#

tho i had other issues

#

forgot to get leds to be mutable that is ok I fixed

#

the function now recieves a mutable reference to the array pins but i says mismatched types

#
Checking simple_bartender v0.1.0 (C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\simple_bartender)
error[E0308]: mismatched types
   --> src\state.rs:57:35
    |
57  |                 self.serve_drinks(&mut self.pins);
    |                      ------------ ^^^^^^^^^^^^^^ expected array of 4 elements, found mutable reference
    |                      |
    |                      arguments to this function are incorrect
    |
    = note:          expected array `[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
            found mutable reference `&mut [avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
note: associated function defined here
   --> src\state.rs:104:8
    |
104 |     fn serve_drinks(&mut self, &mut pins:RelayPins) {
    |        ^^^^^^^^^^^^ ---------  -------------------
help: consider removing the borrow
    |
57  -                 self.serve_drinks(&mut self.pins);
57  +                 self.serve_drinks(self.pins);
    | 

error[E0308]: mismatched types
   --> src\state.rs:104:32
    |
104 |     fn serve_drinks(&mut self, &mut pins:RelayPins) {        
    |                                ^^^^^^^^^----------
    |                                |         |
    |                                |         expected due to this
    |                                expected array of 4 elements, found `&mut _`
    |                                help: did you mean `pins`: `&[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
    |
    = note:          expected array `[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
            found mutable reference `&mut _`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `simple_bartender` due to 2 previous errors
#

K so..

#

The variable in main did not need to be mutable

#

But it said in the signature

#

So now it is

#
serve_drinks(&mut self, mut pins:RelayPins)```
#

But now I have a new error and this time I don't feel like I can fix it

#
Checking simple_bartender v0.1.0 (C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\simple_bartender)
error[E0507]: cannot move out of `self.pins` which is behind a mutable reference                                                                  
  --> src\state.rs:57:35
   |
57 |                 self.serve_drinks(self.pins);
   |                                   ^^^^^^^^^ move occurs because `self.pins` has type `[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`, which does not implement the `Copy` trait

error[E0505]: cannot move out of `self.pins` because it is borrowed
  --> src\state.rs:57:35
   |
57 |                 self.serve_drinks(self.pins);
   |                 ------------------^^^^^^^^^-
   |                 |                 |
   |                 |                 move out of `self.pins` occurs here
   |                 borrow of `*self` occurs here

Some errors have detailed explanations: E0505, E0507.
For more information about an error, try `rustc --explain E0505`.
error: could not compile `simple_bartender` due to 2 previous errors
#

@old mango any idea?

#

@hallow hinge or maybe you?

#

And why not @dreamy trellis

old mango
#

Can you do it as a mut ref?

wary cloak
#

When I'm calling the function or in the signature?

#

In any case I think it will display the error mismatched types again

old mango
#

It'd naturally be for both?

wary cloak
#

I will do it so you see the errors

#

First I will show how they are rn

#

And then well do the mutable referencea

#

Rn they are

wary cloak
#
self.serve_drinks(self.pins);```
#

Calling

#

Now let's change it

#
fn serve_drinks(&mut self, &mut pins:RelayPins)```
#
self.serve_drinks(&mut self.pins)
old mango
#

Nvm, with the way you're calling that borrowck will refuse

wary cloak
#

It does but

#

You wanna see the error message?

old mango
#

It'd be something like cannot move out of ref for the original and can't borrow twice for the changed, right?

#

Can you get rid of the pins argument and just use self.pins inside serve_drinks?

wary cloak
#

no, mistmatched types i think is the error

#
error[E0308]: mismatched types
   --> src\state.rs:57:35
    |
57  |                 self.serve_drinks(&mut self.pins);
    |                      ------------ ^^^^^^^^^^^^^^ expected array of 4 elements, found mutable reference
    |                      |
    |                      arguments to this function are incorrect
    |
    = note:          expected array `[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
            found mutable reference `&mut [avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
note: associated function defined here
   --> src\state.rs:104:8
    |
104 |     fn serve_drinks(&mut self, &mut pins:RelayPins) {
    |        ^^^^^^^^^^^^ ---------  -------------------
help: consider removing the borrow
    |
57  -                 self.serve_drinks(&mut self.pins);
57  +                 self.serve_drinks(self.pins);     
    | 

error[E0308]: mismatched types
   --> src\state.rs:104:32
    |
104 |     fn serve_drinks(&mut self, &mut pins:RelayPins) {
    |                                ^^^^^^^^^----------
    |                                |         |
    |                                |         expected due to this
    |                                expected array of 4 elements, found `&mut _`
    |                                help: did you mean `pins`: `&[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
    |
    = note:          expected array `[avr_hal_generic::port::Pin<Output, Dynamic>; 4]`
            found mutable reference `&mut _`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `simple_bartender` due to 2 previous errors
wary cloak
#

I get rid of the mut references then?

#

Tho that's basically what the compiler suggests

old mango
old mango
wary cloak
#

Ok let's see

#

Well..

#

That solved it

#

It seems

#

Could you explain me why?

old mango
#

You know how rust only lets you take one mutable reference to an object at a time, right?

wary cloak
#

Yes

#

The code works but.. Weirdly.

old mango
#

And also you cant move a value out of a variable while you hold a reference to it?

wary cloak
#

Repeat me that

#

That got me a little confused

#

I may know but I can't visualize it

old mango
#

When you say "let a = b" in rust, when b isnt a reference, it moves the value from the binding b to the binding a; the value can no longer be accessed through b because b doesnt own that value anymore

wary cloak
#

God f damn it the code works but in a weird way and I can't seem to determine the issue -

wary cloak
#

Unless it implements copy

old mango
#

When you transfer ownership like that, any references you had to the value, that are references to b, stop being valid
This is because the value isnt in b anymore, it's in a now, and the references have no way of knowing that

old mango
wary cloak
#

Ok I get that

old mango
#

Therefore, when you transfer ownership (move the value), old references to the value from before the move stop being valid
Rust makes sure you can't accidentally still use one of those references by saying "if there's still a reference to it, you don't get to transfer the ownership of that value"

wary cloak
#

Mmm ok

old mango
#

Awesome

#

Aight, now, looking at the original signature of serve_drinks, it's serve_drinks(&mut self, mut pins: RelayPins)
The pins parameter here, since it's not a reference, will take ownership of whatever is passed in that parameter
So when you call
self.serve_drinks(self.pins), it can't comply

wary cloak
#

Wait

#

Was I

#

Taking a mutable reference to self

#

While also

#

Asking for owner ship?

old mango
#

Yup

wary cloak
#

Or at the very least another mutable reference

#

I see I used self two times

old mango
#

Mutable reference, and asking for ownership

wary cloak
#

In the other hand I asked only one mutable reference to self inside I could refer to things from self so

#

Ah btw

old mango
#

Also, i'm guessing that the place where this function call occurs is another function on the same struct?

wary cloak
#

I fixed 89% of what I just said of the code working but doing it weirdly

wary cloak
old mango
#

If the self in self.serve_drinks(self.pins) is a mut ref in the first place, it's completely impossible to move out of it

wary cloak
#

Man I can't believe it if this was Arduino I would've gotten stuck but with rust I could confidently solve and figure out 90% of the errora

#

Errors*

#

What a pleasure

#

Also now I can't live without modules

old mango
#

This is because a mutable reference isn't ownership; to give serve_drinks ownership of that object, you'd have to have ownership of the object already, but since it's a mutable reference, you can't do that.
For the function knows, when it returns and that &mut self goes out of scope, the actual owner of self will keep on using it

wary cloak
#

Oh of

old mango
#

So if you wanted to transfer ownership all the way down, you'd need to use fn my_fn(self, <other parameters>) all the way down

wary cloak
#

Update already takes a mutable reference to self also

old mango
#

And that also wouldn't work, because it's in a loop, so after you call it, it'll get called again, except the ownership would've already been transferred, and you wouldnt have anything to call the function on anymore

#

Thus, the only option all along was to pass &mut self all the way down

#

Any other questions or are you good for now?

wary cloak
#

I think I'm good

#

Thank you very much

old mango
#

Aight, awesome

wary cloak
old mango
#

No probs

wary cloak
#

@coral geyser it didn't work again-

#
C:/Users/Taller03/Desktop/simple_bartender # cargo check
    Updating crates.io index
  Downloaded paste v1.0.8
error: failed to unpack package `paste v1.0.8`

Caused by:
  failed to unpack entry at `paste-1.0.8/.cargo_vcs_info.json`

Caused by:
  failed to unpack `D:/rust_toolchain/.cargo\registry\src\github.com-1ecc6299db9ec823\paste-1.0.8\.cargo_vcs_info.json`

Caused by:
  failed to set mtime for `D:/rust_toolchain/.cargo\registry\src\github.com-1ecc6299db9ec823\paste-1.0.8\.cargo_vcs_info.json`

Caused by:
  El parámetro no es correcto. (os error 87)
C:/Users/Taller03/Desktop/simple_bartender #

#

Why this time ;;

#
Windows PowerShell
Copyright (C) Microsoft Corporation. Todos los derechos reservados.

Prueba la nueva tecnología PowerShell multiplataforma https://aka.ms/pscore6

PS C:\Users\Taller03> cd D:/
PS D:\> cd rust_toolchain
PS D:\rust_toolchain>   .\busybox.exe ash setup_rust_arduino.sh
Directory of rust toolchain: D:/rust_toolchain
Starting configured ash shell, run 'exit' to exit the shell.
D:/rust_toolchain $ cd ..
D:/ $ cd simple_bartender
D:/simple_bartender $ cargo check
error: failed to download `paste v1.0.8`

Caused by:
  unable to get packages from source


Caused by:
  failed to unpack package `paste v1.0.8`

Caused by:
  failed to unpack entry at `paste-1.0.8/.cargo_vcs_info.json`

Caused by:
  failed to unpack `D:/rust_toolchain/.cargo\registry\src\github.com-1ecc6299db9ec823\paste-1.0.8\.cargo_vcs_info.json`

Caused by:
  failed to set mtime for `D:/rust_toolchain/.cargo\registry\src\github.com-1ecc6299db9ec823\paste-1.0.8\.cargo_vcs_info.json`

Caused by:
  El parámetro no es correcto. (os error 87)
D:/simple_bartender $
#

Here in PowerShell

#

Even with not embedded projects like guessing_game it doesn't work-

#
error: failed to unpack package `winapi-x86_64-pc-windows-gnu v0.4.0`

Caused by:
  failed to unpack entry at `winapi-x86_64-pc-windows-gnu-0.4.0/Cargo.toml`

Caused by:
  failed to unpack `D:/rust_toolchain/.cargo\registry\src\github.com-1ecc6299db9ec823\winapi-x86_64-pc-windows-gnu-0.4.0\Cargo.toml`

Caused by:
  failed to set mtime for `D:/rust_toolchain/.cargo\registry\src\github.com-1ecc6299db9ec823\winapi-x86_64-pc-windows-gnu-0.4.0\Cargo.toml`

Caused by:
  El parámetro no es correcto. (os error 87)
coral geyser
#

Um, try adding a --offline to the cargo command

wary cloak
#

What do we do?

#

It has been two weeks it's so shitty that it's only one class a week

#

We just can't get it to work-

wary cloak
#

But

#

That's for the embedded scenario or not embedded scenario

#

Because the error messages were different

#

And also we can't test it now that I'm at home, I hope we could so this didn't happen again

#

Are you use there's nothing else we might need?

coral geyser
#

I don't think anything else is needed, though this is my first time attempting this so

coral geyser
#

both

#

well, actually the usb drive isn't setup to do not embedded

#

but is should be able to do it anyways

#

the main issue seems to be cargo really hates being on a fat32 filesystem

#

which we can only salve by reformatting the usb

#

which we could do

wary cloak
#

Since it isn't my maybe we shouldn't-

#

I have one to be mine but not the time to go through all that pain again

wary cloak
#

That would be it?

coral geyser
#

yeah, though i am not sure if it will actually fix it more of like the best next step to check

wary cloak
#

The thing is if it doesn't work and it's another week

#

Btw

#

Think you could help me with the Arduino version? It's just, it's kinds close to finish and I want sooo badly to get it out of the way

coral geyser
#

what is the issue?

wary cloak
#

Did I told you what I was doing with the rfid why it's there?

coral geyser
#

yeah

wary cloak
#

Well I'm stuck in the last functionality that is the password system

#

It can tell if the password you enter is correct or not

#

But then it doesn't perform the password change.

#

And I got prints every where to see where's stuck

#

And I got out of ideas of what to do

#

And it's weird I more or less copy pasted from my change password code that works

#

So the fact that this one doesn't

#

Is weird

#

What's left to do is

#

For the thing to actually change the password when the password is correct

#

To the error handling so if you get a card that it's already fine it tells you, hey this one's already good and goes back

#

And the whole EEPROM deal..

#

But it seems decently simple to work with the EEPROM

#

And after that's done

#

I should get that and all the other the rfid functionality I already have working like buying and stuff

#

To the base functionality of the project

#

After that, well the sensors which are really easy to work with today I learned how to work with the ultrasound one

#

And tested that it worked for water too

#

And the other is likely easier than that one so

#

As you see, it's so close to be finished

coral geyser
#

can I get the code?

wary cloak
#

Sure

#

I have plenty rfid codes

#

-reading for default password

-reading for password I want

-change password of one sector

-change password of all sectors

-and this one the prototype of the functionality

#

I'm building the passwords an all on top of that one

#

You want the full code or the function?

#

Tho have you worked with that library before? It was so hard for me to understand and it was a whole deal to more or less get it and start actually doing something

#

Because I think I have over there the git repository if you'd like

coral geyser
wary cloak
#

Sure

#
#include <SPI.h>
#include <MFRC522.h>
 
#define RST_PIN 5
#define SS_PIN 53
 
MFRC522 mfrc522(SS_PIN, RST_PIN);
 
MFRC522::MIFARE_Key keyA = {keyByte: {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5}};
MFRC522::MIFARE_Key keyB = {keyByte: {0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5}};

byte sector = 15;
byte numBloque = 60;
byte bloqueTrailer = 63;
 
void mostrarByteArray(byte* buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

char waitForOption(void)
{
  while (!Serial.available());
  char dato = Serial.read();
  while (Serial.read() != 10);
  return dato;
}

bool obtenerPlata(char *plata){
    int i;
    for (i = 0; i < 15; ++i)
    {
        char input = waitForOption();
        if (input >= '0' && input <= '9') {
          plata[i] = input;
        } else break;
    }

    plata[i] = '\0';
    return i;
   
  }

char* waitForPassword(char* password, char* user_password){
  int i;
  for(i=0;i<strlen(password);i++){
    char input = waitForOption();
    user_password[i] = input;
  }
  user_password[i] = '\0';
  return user_password;
}

int obtenerSaldo(){
  unsigned char datosBloque[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  byte arraySize = 18;
  mfrc522.MIFARE_Read(numBloque,datosBloque,&arraySize);
  String saldo_actual = String((char*)(datosBloque));
  int saldoActual = saldo_actual.toInt();
  return saldoActual;
}



void setup() {
  Serial.begin(9600);
  while (!Serial);      
  SPI.begin();
  mfrc522.PCD_Init();

}

#
void loop() {
  Serial.println("\n¿Quiere acceder al modo maestro u operar normal?");
  Serial.println("1-Modo Maestro");
  Serial.println("2-Modo Normal");

  char input = waitForOption();

  switch (input) {
    case '1':{
      modoMaestro();
      return;
    }
    case '2':{
      modoNormal();
      return;
    }
    default:
      Serial.println("Elija una opcion valida");
      return;
  }
}

void modoNormal() {
  Serial.println("\n¿Quiere cargar plata, comprar o verificar su saldo?");
  Serial.println("1-Cargar Plata");
  Serial.println("2-Comprar");
  Serial.println("3-Ver estado de saldo");

  char input = waitForOption();

  switch (input) {
    case '1':{
      cargarSaldo();
      return;
    }
    case '2':{
      comprar();
      return;}
    case '3':{
      leerSaldo();
      return;}
    default:
      Serial.println("Elija una opcion valida");
      return;

  }
}


void cargarSaldo() {

  char plata[16];
  unsigned char datosBloque[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

  Serial.println("ingrese la cantidad de dinero que desea cargar y finalice con cualquier letra");
  bool esNumero = obtenerPlata(plata);
  if(esNumero == false){
    Serial.println("No ingreso un numero");
    return;
  }

  Serial.println("Ahora acerque la tarjeta para cargarle plata");
  while(!mfrc522.PICC_IsNewCardPresent());
  while(!mfrc522.PICC_ReadCardSerial());

  mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, &keyA, &(mfrc522.uid));
 
  String plataAEscribir = String(obtenerSaldo() + String(plata).toInt());
 
  plataAEscribir.toCharArray((char*)datosBloque, 16);
  mostrarByteArray(datosBloque,16);

  mfrc522.MIFARE_Write(numBloque,datosBloque,16);
 
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
 
  return;
}
#
void comprar() {
  unsigned char datosBloque[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
  Serial.println("Elija un producto");
  Serial.println("1-Fernet con Coca 400$");
  Serial.println("2-Sex on the beach 250$");
  Serial.println("3-Agua 100$");
 
  char input = waitForOption();

  int precio = 0;

  switch (input) {
    case '1':
      precio = 400;
      break;
    case '2':
      precio = 250;
      break;
    case '3':
      precio = 100;
      break;
    default:
      Serial.println("Elija una opcion valida");
      return;
  }

  Serial.println("Ahora acerque la tarjeta para reaizar su pago");
     
      while(!mfrc522.PICC_IsNewCardPresent());
     
      while(!mfrc522.PICC_ReadCardSerial());

      mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, &keyA, &(mfrc522.uid));

      int saldo = obtenerSaldo();

      if(saldo < precio){
        Serial.print("Su saldo es insuficiente");
        mfrc522.PICC_HaltA();
        mfrc522.PCD_StopCrypto1();
        return;
      }
     
      String plataADescontar = String(obtenerSaldo() - precio);
      plataADescontar.toCharArray((char*)datosBloque, 16);
      mfrc522.MIFARE_Write(numBloque,datosBloque,16);

      Serial.println("Proceso terminado disfrute de su bebida");

      mfrc522.PICC_HaltA();
      mfrc522.PCD_StopCrypto1();

  return;
 }



void leerSaldo() {
  Serial.println("Apoye su tarjeta para ver su saldo");

  while(!mfrc522.PICC_IsNewCardPresent());
  while(!mfrc522.PICC_ReadCardSerial());

  mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, &keyA, &(mfrc522.uid));

  int saldo = obtenerSaldo();

  Serial.print("Su saldo actual es ");
  Serial.print(saldo);

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();

  return;
}
#

And this last function I'm going to send

#

Is ther one I was trying to debug

#
void modoMaestro(){
  char password[] = {'c','a','d','3','6','5','\0'};

  Serial.println("Ingrese la contraseña");

  char user_password[6];
 
  waitForPassword(password, user_password);

  byte verificacion = strcmp(password,user_password);

  if(verificacion == 0){
    Serial.println("Contraseña correcta, acerque la tarjeta al lector");

    MFRC522::MIFARE_Key keyA = {keyByte : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
    MFRC522::MIFARE_Key keyB = {keyByte : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};

    MFRC522::MIFARE_Key nuevaKeyA = {
    keyByte : {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5}};
    MFRC522::MIFARE_Key nuevaKeyB = {
    keyByte : {0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5}};


    const byte sector = 15;
    for(;;){
    if (!mfrc522.PICC_IsNewCardPresent()) {
      Serial.print(!mfrc522.PICC_IsNewCardPresent());
      continue;
    }
   
    if (!mfrc522.PICC_ReadCardSerial()) {
      Serial.print(!mfrc522.PICC_ReadCardSerial());
      continue;
    }

    Serial.print(" chau if's");


    byte bloqueTrailer = sector * 4 + 3;
    byte buffer[18];
    byte size = sizeof(buffer);

    Serial.print(" chau variables");

    mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, &keyA, &(mfrc522.uid));
    mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, &keyB, &(mfrc522.uid));

    Serial.print(" chau autenticacion");

    if (nuevaKeyA.keyByte != nullptr)
    for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++)
      buffer[i] = nuevaKeyA.keyByte[i];

      Serial.print(" chau primer null");

    if (nuevaKeyB.keyByte != nullptr)
      for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++)
       buffer[i + 10] = nuevaKeyB.keyByte[i];

       Serial.print(" chau segundo null");

    mfrc522.MIFARE_Write(bloqueTrailer, buffer, 16);

    Serial.print(" chau escritura");

    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();

    Serial.print(" chau stops");

    Serial.println("Proceso Finalizado");

#
     Serial.print(" chau funcion");
    break;
  }

  } else{
  Serial.println("Contraseña Incorrecta");
  return;
  }
 }
#

Do you want the place where I got the library from and the git repository?

#

Here I saw it and the examples

#

Understanding the code there and all was mostly all I had

#

And here's the git repository which well

#

When I didn't know about cpp and OOP it wasn't that useful

#

Not like it is that much now but

wary cloak
#

If you know about normal cpp Arduino you could help in this other thing too @hallow hinge

wary cloak
#

@old mango do you think you might be able to help with this? Not rn tho

old mango
#

I am about to go back to sleep so yeah not rn

#

When i wake up, prolly?

#

What exactly is it that you need?

wary cloak
#

Make that code work(?

wary cloak
#

And also the functionality it would provide it's one I did I a code dedicate only to that and it worked but here copying code from there

old mango
#

Why's this but in c++, btw?

wary cloak
#

Didn't

wary cloak
old mango
#

Was just wondering since i thought the project was in rust; or maybe I'm misunderstanding

#

I'll take a look at the code in ~8 horas

wary cloak
#

Sure

wary cloak
old mango
#

Ah

wary cloak
#

But since this one is so close to finish I want to finish it once and for all

#

And also you said I asked you help for cpp issues

wary cloak
#

@coral geyser will you be able in some minutes?

wary cloak
#

Available*

hallow hinge
#

Hi. :3

#

This time I'm available fr

#

I had some things to do irl so I was unavailable

wary cloak
#

Sure

wary cloak
#

Question or whatever

#

The only thing that happened is that the base functionality was completed

#

But now as you may see I really want to end the original Arduino one, I'm sick of it at least sick of the rfid part

#

Tho when finishing the rfid part is almost like finishing the project because the sensors are easy

wary cloak
wary cloak
#

@hallow hinge @coral geyser are any of you two available now or maybe like in 40 minutes? Both work fine

#

Tho it you don't I get to sleep earlier today so in any case (?

#

if you*

old mango
#

@wary cloak aight, you wanted some help with that RFID code?

#

available for a bit atm

wary cloak
#

Yes but I won't code tonight

#

We could like.. The setup talk

#

Details, doubts, preparing to be able to code

#

So next time likely tomorrow

#

We can get right into it

#

Just above I sent the whole code, aside from that the place where I got the library from, and most importantly, the git repository

old mango
#

So, uh, quick issues I saw on a quick readthrough of modoMaestro:

// WRONG: `password[]' has 7 chars (including the '\0'), and waitForPassword will write 6 chars + a '\0', so this will in fact overwrite some unrelated location in memory!!!
// BAD PRACTICE: if the length of `password[]' changes, it could potentially cause the above problem to become even worse.
// VERDICT: This is a buffer overrrun, seriously not good. You might not see any effects, but this is a really bad thing to have.
char user_password[6];
// BETTER VERSION:
// NOTE: sizeof(password) returns the size of password in *bytes*, not the size in terms of the elements in it. While for a char[] array, these two will be the same, this is a better practice.
char user_password[sizeof(password) / sizeof(char)];

// WRONG: `strcmp' returns a signed `int', but `byte' is unsigned.
//   PROBLEM 1: `byte < 0' is always false because `byte' is unsigned, which discards part of the functionality of `strcmp'.
//   PROBLEM 2: `int' is larger than `byte'. Therefore, when you assign an `int' to a `byte', it will truncate whatever parts of the `int' that the `byte' cannot hold. Therefore, certain values of int, like -256, for example, would actually turn into 0 when you try to convert them to a byte. Now, due to the specification of `strcmp', this shouldn't actually happen here, but it's still bad practice.
// VERDICT: Works okay, but only due to technicalities and the fact that your code only does an equality check with 0.
byte verification = strcmp(password, user_password); // CURRENT
// BETTER VERSION:
int verification = strcmp(password, user_password);

// PROBABLE BUG: This is using `keyB' but the command is `PICC_CMD_MF_AUTH_KEY_A'; I think you might be supposed to use `PICC_CMD_MF_AUTH_KEY_B'?
mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, &keyB, &(mfrc522.uid));

(part 1/2)

#
// Stylistic issue
if (nuevaKeyA.keyByte != nullptr)
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++)
  buffer[i] = nuevaKeyA.keyByte[i];

  Serial.print(" chau primer null");
// With braces, it's the following, which seems to go against the indentation your using.
if (nuevaKeyA.keyByte != nullptr) {
  for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
    buffer[i] = nuevaKeyA.keyByte[i];
  }
}
Serial.print(" chau primer null");
#

Also, not sure what's up with your buffer.
It's declared to be 18 bytes, but the documentation says the sectors are 16 bytes, and MIFARE_Write says it will write exactly 16 bytes.
I'm also unsure about the buffer[i+10] = nuevaKeyB.keyByte[i];
Reading the file you linked (MFRC522.h), this would mean that buffer would be AAAAAA????BBBBBB where the A's are the bytes of keyA, the B's are bytes of keyB, and the ? are literally just random bytes of garbage floating around in the Arduino's memory.
Since buffer isn't initialised to anything, it's value will literally just be whatever happened to be written to memory at that location before, which is essentially going to be random. I didn't look over the rest of your code since you said it was modoMaestro you were looking for help with, but if having random junk written there is a problem, you'll want to memset(buffer, 0, 16); or change the declaration to byte buffer[/* whatever the size is */] = { 0, 0, /* ... */, 0 };.

#

Anyway, when/if you have questions, just ping me; I have a couple thousand lines of typescript to finish refactoring atm so I'll be getting back to that.

wary cloak
#

@old mango well I more or less read it, I'm still asleep so I don't get it at all but

#

I may answer some stuff

#

First

#

Read needs an 18 byte buffer, why? I don't remember but it was in the documentation and if I used a 16 byte one it would say that the buffer was small

hallow hinge
#

Hi. :3 are you available rn? Because if so, I'm available too lol

#

Oh wait

#

Is this C++ tho?

old mango
#

yat

wary cloak
#

Also the majority of the code there is from a code only dedicated to changing the password that worked perfectly but I don't know why it does now

#

Doesn't now*

#

The other thing was..

#

Ah you see those prints

#

To debug

#

"Chau autenticacion"

#

Is the last one I see when running the code

hallow hinge
#

Reads 16 bytes (+ 2 bytes CRC_A) from the active PICC.

#

For MIFARE_Read

wary cloak
#

I have no idea why the null ptr is there I tried to remove it but it doesn't seem to be that and it could cause it not your work

#

Not to*

old mango
#

Ahh, that makes a lot more sense

hallow hinge
#

Though, MIFARE_Write really only uses 16 bytes, yeah.

#

bufferSize Buffer size, must be at least 16 bytes. Exactly 16 bytes are written.

wary cloak
#

Also for now the password isn't going to change but ofc in the future when the basic part of that working it will

#

And yeah I don't remember since I did this long ago

#

Why I'm only verifying key A

#

But it worked, it's the key I need I guess because for sector 15 A has the right to write and read ig

old mango
#

huh

wary cloak
#

Well there's that, if it helped I could also bring here the code that does what modo maestro should and worked

old mango
#

aight, sounds good

wary cloak
#

I see almost no difference between the two aside from removing all the not necessary stuff like status code and so

old mango
#

what is it precisely that you wanted help with, btw?

#

just debugging the modoMaestro?

wary cloak
#

For now because I can't advance if that function doesn't work but after that I need to do more

#

I have to wash my face and brush my teeth after that I'll look for the message where I explained RFID functionalities in my project

wary cloak
hallow hinge
#

Ah. :3

#

doesn't have the time to talk about architecture >-<"

#

(Also, you probably shouldn't talk about architecture with me either. : P I have extended 20 minute meetings into 1 hour in $WORK)

wary cloak
#

We aren't talking about architectue but for example what the code does what's the issue and so on

old mango
#

i would love to talk about architecture but i also i don't think i know enough to be interesting conversation 😔

wary cloak
#

So you can go there and see what the RFID is supposed to do so you understand the end goal of the code and in which stage are we

#

Close to finish if what's left isn't that hard

#

And later after you read that I can bring in the other code

old mango
#

so, you have an RFID card that lets you store data onboard?

#

just making sure i understood everything correctly

#

then you store a password on that card?
also you have somewhere a financial system, where that card acts as an identifier
this is the code to set that password on the card
and additionally there's a master password stored in the mega EEPROM that's set at first boot

wary cloak
#

More or less yes

#

Now we are making so that the master mode when the password is correct and the checking the password works so

#

It changes the password of the card read

#

To have the password that it's allowed in my project

#

So I don't change all of them manually via the other code

#

Honestly for me, with the financial system it was enough

#

My teacher wanted this

wary cloak
old mango
#

balance is in sector 60 as a 15-digit number (btw, that's potentially an issue—an int on an arduino Mega is 16 bits, and 10^15 is much greater than 2^15-1)
and then password is in sector 63?

wary cloak
#

We first have to make it so when in master mode, passwords in sector 15 are changed that doesn't happen now, then the error handling and finally the work with EEPROM so the user can set it's own password and change it

#

If I run the code and run master mode

#

I see this

#
¿Quiere acceder al modo maestro u operar normal?
1-Modo Maestro
2-Modo Normal

¿Quiere cargar plata, comprar o verificar su saldo?
1-Cargar Plata
2-Comprar
3-Ver estado de saldo
Apoye su tarjeta para ver su saldo
Su saldo actual es 0
¿Quiere acceder al modo maestro u operar normal?
1-Modo Maestro
2-Modo Normal
Ingrese la contraseña
Contraseña correcta, acerque la tarjeta al lector
1111111111111111111111111111111111 chau if's chau variables chau autenticacion
#

It get's stuck at the null ptr part

#

Ah yes that time I got first the the normal one

#

Then master

#

Now if you want I can show you the change password in one sector code that works

old mango
#

sure

#

yeah, if it's only getting to 'chau autenticacion' something weird is going on

#

there don't seem to be any divergence points there

wary cloak
#
#include <MFRC522.h>
#include <SPI.h>
#include <stdarg.h>

#define RST_PIN 5
#define SS_PIN 53

MFRC522 mfrc522(SS_PIN, RST_PIN);

void mostrarByteArray(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void imprimir(char *format, ...) {

  const byte size = 500;
  char buffer[size];

  va_list args;
  va_start(args, format);

  vsnprintf(buffer, size, format, args);
  Serial.print(buffer);

  va_end(args);
 
}
void setup() {

  MFRC522::MIFARE_Key keyA = {keyByte : {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5}}; //0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  MFRC522::MIFARE_Key keyB = {keyByte : {0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5}}; //0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF




  Serial.begin(9600);
  while (!Serial);
  SPI.begin();        
  mfrc522.PCD_Init();

  imprimir("%s\n%s\n%s",
    "Acerca la tarjeta al lector para escanear.",
    "Las claves de esta tarjeta deben ser:",
    "Key-A: "
  );

  mostrarByteArray(keyA.keyByte, MFRC522::MF_KEY_SIZE);
  Serial.print("\nKey-B: ");
  mostrarByteArray(keyB.keyByte, MFRC522::MF_KEY_SIZE);

  imprimir("\n%s\n%s\n",
    "MUY IMPORTANTE: durante el proceso de actualización de las claves ",
    "no separes la tarjeta del lector hasta que no termine."
  );


  MFRC522::MIFARE_Key nuevaKeyA = {
    keyByte : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}//0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5
  };
  MFRC522::MIFARE_Key nuevaKeyB = {
    keyByte : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}//0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5
  };

  const byte sector = 15;
#

Sorry I got mixed because of the annoying word limit of discord

#

Let me think were was I at

#
for (;;) {
    if (!mfrc522.PICC_IsNewCardPresent()) {
      continue;
    }
   
    if (!mfrc522.PICC_ReadCardSerial()) {
      continue;
    }

    Serial.print(F("UID de la tarjeta:"));
    mostrarByteArray(mfrc522.uid.uidByte, mfrc522.uid.size);

    boolean resultado = cambiarKeys(&keyA, &keyB, &nuevaKeyA, &nuevaKeyB, sector);

    MFRC522::MIFARE_Key *keyAToPrint = resultado? &nuevaKeyA : &keyA;
    MFRC522::MIFARE_Key *keyBToPrint = resultado? &nuevaKeyB : &keyB;

    imprimir("%s %d\n%s",
      "Claves del sector", sector,
      "Key-A: "
    );
    mostrarByteArray(keyAToPrint->keyByte, MFRC522::MF_KEY_SIZE);
    Serial.print("\nKey-B: ");
    mostrarByteArray(keyBToPrint->keyByte, MFRC522::MF_KEY_SIZE);
    Serial.println();

    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();

    Serial.println(F("Proceso finalizado. Ya puedes retirar la tarjeta del lector RFID"));
  }
}
#
boolean cambiarKeys(MFRC522::MIFARE_Key *antiguaKeyA,
                    MFRC522::MIFARE_Key *antiguaKeyB,
                    MFRC522::MIFARE_Key *nuevaKeyA,
                    MFRC522::MIFARE_Key *nuevaKeyB, int sector) {

  MFRC522::StatusCode estado;
  byte bloqueTrailer = sector * 4 + 3;
  byte buffer[18];
  byte size = sizeof(buffer);

  imprimir("\nModificando sector: %d\n", sector);

  estado = mfrc522.PCD_Authenticate(
      MFRC522::PICC_CMD_MF_AUTH_KEY_A, bloqueTrailer, antiguaKeyA,
      &(mfrc522.uid)
  );

  if (estado != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo en la autenticación Key-A: "));
    Serial.println(mfrc522.GetStatusCodeName(estado));
    return false;
  }

  Serial.println(F("Información en el sector: "));
  mfrc522.PICC_DumpMifareClassicSectorToSerial(
    &(mfrc522.uid), antiguaKeyA, sector
  );
  Serial.println();

  imprimir("Leyendo datos del bloque %d...\n", bloqueTrailer);

  estado = mfrc522.MIFARE_Read(bloqueTrailer, buffer, &size);

  if (estado != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo al leer el bloque: "));
    Serial.println(mfrc522.GetStatusCodeName(estado));
    return false;
  }

  imprimir("Información en el bloque %d:\n", bloqueTrailer);
  mostrarByteArray(buffer, 16);
  Serial.print("\n\n");
 
  estado = mfrc522.PCD_Authenticate(
    MFRC522::PICC_CMD_MF_AUTH_KEY_B, bloqueTrailer,
    antiguaKeyB, &(mfrc522.uid)
  );

  if (estado != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo en la autenticación Key-B: "));
    Serial.println(mfrc522.GetStatusCodeName(estado));
    return false;
  }

  if (nuevaKeyA != nullptr)  
    for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++)
      buffer[i] = nuevaKeyA->keyByte[i];

  if (nuevaKeyB != nullptr)
    for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++)
      buffer[i + 10] = nuevaKeyB->keyByte[i];

#
  estado = mfrc522.MIFARE_Write(bloqueTrailer, buffer, 16);

  if (estado != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo al escribir el bloque Trailer: "));
    Serial.println(mfrc522.GetStatusCodeName(estado));
    return false;
  }

  return true;
}
#

Ok done

#

As you will see I only used the relevant parts in modo maestro

#

But maybe I missed something I didn't think it was important

old mango
#

differences:

  • PICC_CMD_MF_AUTH_KEY_B in the second PCD_Authenticate
    I didn't see any other differencees that would seem to be significant
wary cloak
#

See? I don't know why it doesn't work

old mango
#

you said earlier that you purposefully changed that to PICC_CMD_MF_AUTH_KEY_A?

wary cloak
#

And it was the best authentication at least

#

It would have to pass the first check for null an that

#

But not the B one

#

But not even that

old mango
#

oh, actually

#

the code you just posted turns 0xC0C1C2C3C4C5 -> 0xFFFFFFFFFFFF & 0xE0E1E2E3E4E5 -> 0xFFFFFFFFFFFF, whereas your code does the opposite?

wary cloak
#

That's a small detail I just change the passwords because

#

Testing

#

If I already changed the base for mine

#

I can't do it again

#

So I changed back to default

#

That's why there's a comment next to declaring the passwords

#

Show the code to the teacher and test it myself

#

It works either way

#

And the card I'm using has the default password I checked lots of times

#

Anyways I need to go have lunch

old mango
#

aight, i'll read skim the spec rl quik

#

also, i'll probably be going to sleep in the next hour or two

wary cloak
#

Skim?

#

Well I go to school in one hour and something

old mango
#

Ohhhhh, one other huge difference, actually

#

The code that works—it does MIFARE_Read into the buffer before it does MIFARE_Write on the buffer

#

The for loops only set bytes 0-5 and then 10-15 (which are KEY_A and KEY_B, respectively)

#

If the MIFARE_Read occurs first, that means that bytes 6-9 will be initialised properly (these are access control bytes, by the way)

#

However, in the one you wrote, because you removed the MIFARE_Read, bytes 6-9 are just whatever was floating around in the Mega's memory

#

which means the access control bytes were getting set to (basically) random junk

#

I'm not entirely clear on what issues you were having with this system but I imagine that could easily cause problems

#

Also, reading the spec on the access bytes

Remark: With each memory access the internal logic verifies the format of the access conditions. If it detects a format violation the whole sector is irreversibly blocked.

#

I'm not sure if the library or the RFID card do any validation on writes to the trailer blocks, but if they don't, sector 15 might just be nonoperable at this point

#

to test this, maybe retry the code that originally worked, but using, say, sector 14 instead of sector 15

old mango
#

i will note that i'm still somewhat confused about what exactly the two different keys do, so that may have something to do with something or not

#

Other notes:

#
  • PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, &keyB, &(mfrc522.uid) would fail to authenticate if keyA wasn't the same as keyB
old mango
old mango
#

Anyway, it is late and I'm getting off my computer; i'll probably be available sporadically (discord on phone) for possibly up to the next hour

wary cloak
wary cloak
old mango
#

The issue is that you write 7 chars to that array

#

But it's only declared with 6 bytes

wary cloak
#

For what I read, I need to read the keys with mifare read before I ask for them or smth like that? I don't remember why there was a read there I guess I will just copy it before the null ptr question and after verification

wary cloak
old mango
#

Yep

wary cloak
#

Ok I will change that

#

What I'm more interested in is that of the mifare read because that could be it

old mango
#

That 0 could be overwriting something important; it's a bit of a long shot but there's a very small possibility that it's causing the whole "stop after chau autenticacion" issue

wary cloak
#

I don't see why because it is only for the password

#

And the password passes

#

After that it isn't relevant

#

Because it's verifying the passwords on the sector and bla bla

#

User password and password are just to neglect entry

old mango
#

The issue is that \0 isnt being written to user_password, it's being written to whatever is one byte after it, which could frankly be anything

wary cloak
#

Objective that has been accomplished

#

Oh

#

I see

old mango
#

Again, might be nothing, might be something

#

But yeah, hopefully that can help you get moving again

wary cloak
#

mfrc522.MIFARE_Read(bloqueTrailer, buffer, &size);

#

Maybe by writting this before the null ptr check

#

As you said it was missing

old mango
#

After PCD_Authenticate, before any modifications to buffer

#

Also, i would strongly recommend that you do like the original code and put in at least the stuff that dealt with error handling

wary cloak
#

But when I finish this and I move it to the original project I can't do that error handling with the lcd

#

It should work by it's own without the debbugin tools

old mango
#

That way, if, say, the read fails, it can detect the error and abort the attempt, rather than write possibly invalid data which would kill the sector

wary cloak
#

After any try I read the card again to see if anything changed

#

And it didn't for any reason

#

Any ways likely that's the error because in the if's I change the information in buffer and after them write it to the sector but I never got the buffer with the information first

old mango
wary cloak
#

That doesn't explain at all why it didn't just write whatever and took what was in the buffer or whatever but

#

This may solve it or at least take us a step further

wary cloak
#

I get that it didn't work because originally I should read from the trailer sector to get the access bits we don't know about and then only re write the passwords and pass it to mifare write

#

I get that what I don't get

#

It's why didn't it work, badly but worked

#

With whatever data buffer had

#

Maybe because we didn't have the access bytes in the middle

#

That's why we read it in the first place

#

We know that passwords but not the access bits

#

Anyways I need to prepare to go to school when I come back I can try adding the read and see what happens

old mango
#

Yeah, it might even be that sector 15 is still working fine, too, and it's just that the writes have been failing all this time

#

(Maybe the chip verifies the access bits before actually writing, and's it's just been silently erroring)

wary cloak
#

Yeah that makes sense

#

Maybe with just that we solved the first issue I hope so

#

If we did what's next is the error handling

#

Basically

#

If you try to read a card that already has the correct password and doesn't need to change it will say "this card it's already available for use" Or something and go back to the menu

#

Probably it would be something like try on the read, throw if the password read is the one we are trying to change it to, and catch and print that the card is available and return or whatever

#

Something like that

#

I don't know error handling in cpp so I'm just saying

old mango
#

For error handling, I'd go with returning true/false, or if you need more information, returning an integer error code (or an enum value error code)

#

When i last checked, arduino disabled exception handling by default, i think (exceptions = try/throw/catch), because exceptions involve a lot of hidden code being generated under the hood, which isn't great when you're working in embedded environments with strict resource limits like arduino

wary cloak
#

If it doesn't have the base password and it has the password that my project accepts

#

Basically if you pass the card a second time

#

It detects it and says

#

This card is already good and goes back if not I would get stuck

#

But it won't be only true or false