#Arduino Help

1 messages · Page 6 of 1

wary cloak
#

And since the pins I remember I used 22,23 and so, instead of u8 they would be intergers

#

And what things let us do that -?

coral geyser
#

Pin<..., ...> structs that variable pins holds in main.rs

wary cloak
#

You mean input output ig

#

Because we could in main declares the pins to be input/output and then send them to the new function or something or we could create another struct/enum inside keypad

#

And get rid of the columns and rows fields

coral geyser
#

How about 2 arrays?

#

rows: [Pin<..., ...>; 4], cols: ...

wary cloak
#

What's that inside the array?

coral geyser
wary cloak
#

I'm a little bit confused

coral geyser
#

That let you set and read the pin's state

wary cloak
#

So we are indeed making pin structs?

#

Let's go step by step then.

coral geyser
wary cloak
#

What

#

Oh yes

#

Pins macro creates a struct?

coral geyser
wary cloak
#

Ok so..

#

The pins struct contains all the pins of my board

#

So you suggest

#

That rows and columns

#

Are arrays that contains the specific fields needed from the pins struct

#

Right?

coral geyser
#

Basically

#

You can take the pins out of the struct that holds them

#

Like we did for the i2c

wary cloak
#

And ig brackets for generics or something because I could connect them almost any where

coral geyser
#

And the serial

wary cloak
#

We did that (?

#

When(?

coral geyser
wary cloak
#

do you agree with the idea to have the same key struct from the C code inside the Keypad struct?

coral geyser
wary cloak
#

The key struct has a field for the bit combination and another for the ASCII character to represent each key, tho in my C example for readability I made the matrix with all my key const struct instances

#

To represent each key

#

Tho ig you could also have the ASCII in matrix and a bit field for any key needed set of bits in the display struct

coral geyser
#

So I guess the main question is, are we doing the individual pin or PORTA method?

wary cloak
#

Ig we will do our own struct or whatever to replace it unless it isn't that much of a huge pain

#

Tho I was really considering to use unsafe..

#

Because I know is safe we won't mess up and it saves up so much code

coral geyser
#

Because individual pins don't need bit combinations

wary cloak
#

But how do you track which key is it

coral geyser
#

In the loop ferrisOwO

wary cloak
#

Idk how the condition would be because that would make like 64 conditions

coral geyser
#
for r, row in rows.enumerate() {
  for c, col in cols.enumerate() {
    
  }
}
wary cloak
#

If pin 1 is this and pin 2 is this and pin 3 is this.. And pin 8 is this

Else

If pin 1 is this..

coral geyser
#

Loops ferrisHmm

wary cloak
#

Mm

#

I just don't get it ig we will see

#

Let's try do individual pins

#

If it's so much of a pain we will use unsafe

coral geyser
#

So we need somewhere to put the pins

wary cloak
#

Wait first

#

So no key struct and no bit field?

coral geyser
#

Yep

wary cloak
#

Just columns and rows which the pins Corresponding to them and the matrix

#

With"

coral geyser
wary cloak
#

Well ok ao

wary cloak
coral geyser
wary cloak
#

Doesn't the pins are already contain in a struct and we are extracting the ones we are using for an array?

coral geyser
# wary cloak Yes

The pins struct in main holds the "handles" to those 8 wires so you can read write to them

wary cloak
#

handles?

coral geyser
#

We need to get them from pins and put them in Keypad for later use

coral geyser
#

It represents something else

wary cloak
#

Is there anything that isn't a pointer (?

wary cloak
#

The thing is also to the eventual new function we should send

#

Hey I will use this pins for this

#

And inside it should take them

coral geyser
#

And put them somewhere

wary cloak
#

In the arrays

coral geyser
#

Exactly

wary cloak
#

So you told me

#

That we get say ownership of the handle or whatever

#

By calling methods into them like into output

coral geyser
wary cloak
#

I thought we should avoid that kind of stuff, agroup related data, avoid writing extra lines

coral geyser
coral geyser
wary cloak
#

So what do we do-

#

Man it hurts so much the absence of a library this should've been the second easiest part

coral geyser
wary cloak
#

in the lcd there was a clear direction of what to do but here it's just from scratch

wary cloak
coral geyser
#

Because you should have them open to look stuff like this up

#

cargo doc --open

wary cloak
wary cloak
wary cloak
#

So I may turn it now

wary cloak
#

Gosh finally

#

I know generics it's just I don't understand like, anyway we will see+

#

-*

#

Avr or Arduino?

coral geyser
wary cloak
#

Pins?

coral geyser
#

I have been meaning to ask what do the different characters before ? mean in your messages?

coral geyser
wary cloak
#

Which ones you mean

#

"-" And "(? "

coral geyser
#

Yeah

wary cloak
#

Mmm hard to explain

#
  • is like maybe
#

Surprise like

#

When someone says something and stops at the last letter

#

What sound dry and serious or something

#

What- sound like you know how I imagine a confused what to sound

coral geyser
#

Okay, makes sense

wary cloak
#

It would be easier if I could make the sounds

#

Tho as the other probably it stuck because of me talking a lot to someone who did something similar or something made it stuck

#

Now about (?

coral geyser
wary cloak
#

It's not necessary a question sometimes I just don't want messages to be dry or I don't want them to be taken as seriously or idk, this one is really complicated and either I'm just use to it or it's use would have to be explained by a psychologist at this point (?

wary cloak
coral geyser
#

Maybe it's like a /s tag

wary cloak
#

Like I mean it but I don't

#

70 fields-

coral geyser
#

ferrisHmm we need more!!!

coral geyser
coral geyser
wary cloak
#

Btw this project that it's peak has, matricial keyboard 4x4, LCD display with I2C, 2 relay modules, an RFID, 4 ultra sound(? ) sensors and one Infrared (?) Sensor

#

Could be done in the raspberry pi pico or there's a pin shortage?

coral geyser
#

100+ pins is the minimum I will accept /j

wary cloak
#

I need a raspberry Pi pico Mega..

coral geyser
#

Pin<[mode], [number]>

wary cloak
#

The first is for input/output the one inside for? And the one in the same brackets

#

What number?

coral geyser
#

The port number

#

PE0 is port E pin 0

wary cloak
#

So my pin has inside information of it's state as input output, it's port and number, right?

coral geyser
coral geyser
wary cloak
coral geyser
#

But I suspect not enough

wary cloak
#

Yeah me too :(

#

It's so sad

#

I have no clue what I'm going to use the raspberry Pi pico on

#

It's likely gonna get dusty

#

I need bigger boards pls raspberry don't do this to me-

coral geyser
wary cloak
#

I will ask you still to set up all so I could be able to work with it but I don't see use in it

coral geyser
#

Go to arduino_hal::port::mode

wary cloak
#

Why embedded need to be so expensive-

wary cloak
wary cloak
coral geyser
wary cloak
#

But I'm frustrated that I'm doing nothing on it

coral geyser
#

Those things can be 1000+ dollars

coral geyser
wary cloak
#

As I showed you

coral geyser
wary cloak
#

Got there

#

Oh right

#

It could analog or digital

#

But..

#

The others..

#

Do I need to know what this modes are?

#

Pin<input/output<type of input/output>, port and pin number>

#

Right?

coral geyser
#

Yep

#

There is also a special thing you can have in the port and pin number position called Dynamic

#

Which let's it be any port and pin (the port and pin are stored inside the Pin struct)

wary cloak
#

Well that seems kinds convenient for us..

coral geyser
#

I know right ferrisHmm

wary cloak
#

We know the type.. We just need a dynamic pin and port..

#

Blinky blinky

coral geyser
#

So what type should cols be?

#

And what type should rows be?

wary cloak
#

Column digital input and rows digital output

coral geyser
#

What type for each?

wary cloak
#

What do you mean there?

coral geyser
#

Or well mode I guess

wary cloak
#

Oh

#

As I said columns input and rows output

coral geyser
#

Input<?> ferrisWhat

wary cloak
#

Digital?

#

Why isn't digital a thing

#

It's literally the default

#

You use 98% of the time

coral geyser
#

Because it's Floating or PullUp

wary cloak
#

What's the difference between the two?

coral geyser
#

Floating pins are basically completely disconnected from anything

#

PullUp ones will go to 5v by default

wary cloak
#

Well there's output at least for rows, that says is configured as digital output

#

Where would I use each one? Which one do I normally use?

#

So either empty or they work as Vcc? Or what?

coral geyser
wary cloak
#

And why would I use pull up instead of floating?

coral geyser
#

Well what happens if you attempt to read a floating pin not connected to anything? We don't know it can report as 1 or 0

wary cloak
#

Why would I read a pin that has nothing to read ferrisHmm

coral geyser
#

You can actually change the state by just moving your hand around it sometimes

coral geyser
wary cloak
#

Eh..

#

The columns

coral geyser
#

And by connected I mean to 0v or 5v

wary cloak
#

Which are inputs

coral geyser
wary cloak
coral geyser
#

Then it isn't connected to the columns

wary cloak
#

Let's see if I can remember with this

#

This is when someone remembered me how a matricial keyboard worked

#

Well not "someone" My teacher

#

Tho this is in

#

Negative logic

#

But replace in your mind 0 and 1(?

#

By default rows are 0

#

Until you press it then it's 1

#

Columns start at 0 but we chose when and how many are 1

#

But ofc the way we use it

#

It's only have 1 at a time to have a 1 and then keep passing it to the right

#

Tho idk

#

How to answer your question

#

Because

#

There are wires connected to the pins

#

And also

#

In Arduino I just passed the pins without worrying about if they had or not to be pull up to know

coral geyser
#

Some ARM code I finally found from an old project ferrisHmm

wary cloak
#

That seems long and complex (?

#

So you know what kind of pins they are and why(?

coral geyser
#

yeah, I can explain it if you want

wary cloak
#

If it ain't complicated

coral geyser
#

So these keypads assuming its one of these

wary cloak
#

What's GPIO btw

#

Yeah it's one of those

#

The third one

coral geyser
coral geyser
#

each switch connects the row wire with a column wire

wary cloak
coral geyser
#

yep

coral geyser
#

the resistors to vcc

wary cloak
#

I don't use resistors I just connect the wires

coral geyser
#

or are they just connected to other pins

wary cloak
#

That

coral geyser
# wary cloak That

So in that case the inputs if they are set to floating don't have 0v or 5v to set that state

#

if no buttons are pressed

wary cloak
#

I realized I mixed input with output all this time here

#

I don't understand why resistors change that

coral geyser
#

The resistors in the diagram above "pull" the wires towards 5v

wary cloak
#

And why outputs don't need them?

coral geyser
#

The resistors are there to allow you to pull them to 0v to override them

coral geyser
wary cloak
#

So this has to do with inputs needing to be either 0 or 5 volts and being controlled by whoever press them instead of internationally by code?

coral geyser
#

yes

#

If nothing external pulls an input to 0v or 5v we don't know what it will read

wary cloak
#

Oh because there noise that makes it unstable

coral geyser
#

yep

wary cloak
#

So the resistors avoid noise so it could be 0 until it's told to be 5 voy

#

Volt*

#

Ok got it

#

So columns are going to be digital output floating dynamic pins and rows are going to be digital pull up input dynamic pins

#

4 of each

coral geyser
#

We should fix the whole accidentally shorting pins issue

wary cloak
#

Accidentally shorting?

coral geyser
#

I will pull the example from my microelectronics textbook

wary cloak
#

Oooh

coral geyser
wary cloak
#

You mean short circuit by pressing down two at a time

#

Right?

coral geyser
#

yep

wary cloak
#

Tho idk why that short circuits

coral geyser
wary cloak
#

Let get a more base explanation

#

What would you define a short circuit to be

#

And what can cause it and what are the consequences

coral geyser
coral geyser
wary cloak
#

Nah it's the same columns are the lower wires(?

coral geyser
wary cloak
#

Oh wait

#

If columns are input yes

wary cloak
coral geyser
wary cloak
#

So..

coral geyser
wary cloak
#

Ok I get that

coral geyser
wary cloak
#

And micro components would heat and be useless?

coral geyser
wary cloak
#

In what case does this reset the micro instead of killing it?

coral geyser
#

though luckily the arduino pins are protected somewhat against this

wary cloak
#

I heard there were internal resistors in the pins

#

That you could use instead of your own with pull up

coral geyser
wary cloak
#

Ok so now that we more or less understand what a short circuit it's and what it does continue on why two inputs at a time short circuit this

coral geyser
#

So how we fix this issue of 0v connecting 5v is just not have 5v being directly connected to the keypad through output pins

coral geyser
wary cloak
#

I don't see how at all..

#

Because

#

So my outputs would normally

#

Have a 1 constantly moving

#

And the rest 0

#

And the then the inputs

#

Also be all 0

coral geyser
wary cloak
#

Until I press something

#

Ok I get that now

#

But how would that while thing work?

#

Like..

#

They have to be two buttons of the same column

#

Or whichever

#

If they are from the same column we have the column with 1 and two rows in the same column with 1

#

If it's from another the row would be 1 but column 0 at least me I can't see the connection that allows that to happen

coral geyser
wary cloak
#

I just can't see why pressing a second key

#

Connects one column to another

#

Because I only see the connection between a column and it's four rows

coral geyser
#

that will connect 2 different columns together

wary cloak
#

This the kind of thing it's impossible to explain without a whiteboard-

coral geyser
#

you should be able to draw on that

wary cloak
#

i am really bad so let s see..

#

ok so

#

do you see me or it is for me to take a screenshot?

coral geyser
#

are we doing rows or columns as input?

coral geyser
wary cloak
#

as I learn it columns as outputs i control and rows like inputs

#

so

#

say we pressed..

#

row 3 and the 1 is in column 2

#

ok so now

#

we also press r2

#

so..

#

it is like the same

#

two rows in 1 but to the same column

coral geyser
#

what happens if you now press R3,C3

wary cloak
#

it makes the same path of

#

ok lets see

#

do i erase r3 c2?

coral geyser
#

keep them

#

say the 3 in green are pressed

wary cloak
#

three at a time_?

#

well then..

coral geyser
#

what is R3's state?

wary cloak
#

i could see a connection there

#

by pressing two from different columns

#

but not from the same

wary cloak
#

so it is not garanteed short circuit but kinda likely and in any case there should not be even the slightless chance of shortcircuit, right

coral geyser
wary cloak
#

Ok understood

#

So how do we avoid it?

coral geyser
#

So what if instead of using 0 on the output we just made the pin disconnected from the microcontroller

wary cloak
#

Well that makes sense logically because there wouldn't be any Posible 5v to 0v but rather 5v to nothing

#

Tho wouldn't resistors technically do it also?

coral geyser
#

cool, so we do that

wary cloak
#

But how do we make them disconnected?

coral geyser
#

like the ones inside the microcontroller

wary cloak
#

So why don't we use those?

coral geyser
wary cloak
coral geyser
wary cloak
#

I read the description btw and it says

#

OpenDrain Pin is configured as a digital output with open drain behaviour

#

What's open drain behavior and how it works is the thing

coral geyser
#

Open drain acts to connect to 0v when set to low, and disconnect the pin when set to high

wary cloak
coral geyser
wary cloak
#

But I would disconnect it when I want to use it

#

Or I would have to

#

So negative logic?

#

Do*

coral geyser
wary cloak
#

Noooo negative logiiiic ferrisballSweat

#

But I understand

#

That's why the examples seem to always be with negative logic I see

coral geyser
#

Its setup this way because transistors that pull to 0v are smaller than transistors that pull to 5v

wary cloak
#

But 0v would do? Don't we kinda need 5?

coral geyser
#

because chemistry

coral geyser
wary cloak
#

I didn't understand that part honestly

#

First

#

Pull up wasn't to use the resistors inside?

coral geyser
wary cloak
#

Second are we specifying two types for one pin?

wary cloak
coral geyser
wary cloak
#

But..

coral geyser
wary cloak
#

Let's start with inputs

#

So

#

I thought we used pull up on inputs

#

Because of the noise

coral geyser
wary cloak
#

So it could be set to 0 and then to 5 when asked

#

Not that also

coral geyser
#

but it just happens to also fit perfectly for using OpenDrain

wary cloak
#

It made it constantly 5 volts

coral geyser
wary cloak
#

So inputs pull up uses the pin resistor and a default 5 volt state to avoid noise and work with negative logic?

#

And then the outputs would be open drain so there's never a 5v to 0v connection

#

But

#

If the maximum outputs can be is 0 volt

#

What about passing a one as we did before? Like

coral geyser
wary cloak
#

Before two 1's needed to match so

#

I guess when I press it down it would be 0 the row and the column would be either nothing or 0

#

So I guess two 0's would need to match

coral geyser
#

you will see a 0 on the input only when the column is set to 0 and the button connecting them is pressed

wary cloak
#

Ok so now that we talked all of this

#

How we implement it on the struct?

coral geyser
#
rows: [Pin<Input<PullUp>, Dynamic>; 4],
columns: [Pin<OpenDrain, Dynamic>; 4],

ferrisPlead

wary cloak
coral geyser
#

I had an extra >

wary cloak
#

..

#

Where?

#

I don't see it

coral geyser
#

after OpenDrain

#

should just be a ,

wary cloak
#

I thought it should be like input pull up above

coral geyser
#

for some reason it's not

#

No idea why

wary cloak
#

Ok now that we finally had been through all this logic and how it works and we made the struct that holds that matrix of possible ASCII characters with the fixed sizes of 4x4 and the pins for the columns and rows so it could be what ever pin from whatever port but with the fixed size of 4 pins that have the configuration to work as we need them too and avoid short circuits.. What now?

#
struct Keypad {
    rows: [Pin<Input<PullUp>, Dynamic>; 4],
    columns: [Pin<OpenDrain, Dynamic>; 4],
    matrix: [[char; 4]; 4]
}
coral geyser
#

shouldn't X and Y be 4 ferrisPlead

wary cloak
#

Oh yeah I could swear I changed that

coral geyser
#

next step: we need a new function to make these things

wary cloak
#

So

#

New would receive

#

I anotate the types the same way?

#

We could use an alias maybe for the pin types of rows and columns

#

Like

coral geyser
#

type ColumnPin = Pin<OpenDrain, Dynamic>;

wary cloak
#

Type [Pin<Input<PullUp>, Dynamic; 4] = row_pins

#

I forgot how it was

#

But yeah that

coral geyser
#

go ahead

#

if it will help you manage it and read it then its good

wary cloak
#

Shouldn't we use snake case?

coral geyser
#

types are camel case

wary cloak
#

Oh ok

#

?

coral geyser
wary cloak
#

Btw maybe I need a more descriptive name for matrix if any suggestions

wary cloak
coral geyser
# wary cloak

also either you need to make the type aliases arrays or put the arrays in the function signature

coral geyser
wary cloak
#

Oh

coral geyser
#

I am going to switch to Windows real quick

wary cloak
#

By change have any better idea for the matrix type alias?

#

Because matrix is kind of an already existing thing so idk

#
struct Keypad {
    rows: Rowpins,
    columns: ColumnPins,
    matrix: matrix
}

type ColumnPins = [Pin<OpenDrain, Dynamic>; 4];

type Rowpins = [Pin<Input<PullUp>, Dynamic>; 4];

type matrix = [[char; 4]; 4];

impl Keypad {
    fn new(row: Rowpins, column: ColumnPins, matrix: matrix) -> Self {

    }
}
coral geyser
coral geyser
#

naming is hard

wary cloak
#

Ok so

#

I'm still not used to making new functions

#

I know how to do constructors but I don't remember new function being the same in syntax

#

How do I complete new?

coral geyser
#
Self {
  rows,
  columns,
  matrix,
}
coral geyser
wary cloak
#

Solved

coral geyser
wary cloak
#
impl Keypad {
    fn new(row: RowPins, column: ColumnPins, matrix: Matrix) -> Self {
        Self {
            rows,
            columns,
            matrix,
        }
    }
}
#

Ok so know we have a keypad struct with a matrix of the possible ASCII characters and the pins with the already correct setup of rows and columns and a new function

#

Two questions

#

First

#

That means when I declare the pins I want to use I won't be calling into_output and stuff?

coral geyser
wary cloak
#

Also I made the struct and new function public this time I ain't forgetting ferrisHmm

wary cloak
coral geyser
wary cloak
#

Well what's next now?

#

I guess we should

#

Work with ok we have this data

coral geyser
#

what methods do you want this struct to have

#

?

wary cloak
#

How with this data can we make a function to detect the pressed key and return it?

#

Tho to be honest

#

The only thing I really need and use

#

It's waitForKey

#

But I think is very basic to have that functionality also ig

#

So a getKey method and waitForKey method should be enough

#

At least for the purposes and scope of this project

#

Tho

#

There one other use this will have

coral geyser
wary cloak
#

I will tell you in case maaaaybe

coral geyser
#

and just put todo!() in the body of them

wary cloak
#

Another function would do

#

Did I told you about master mode and passwords?

coral geyser
#

you did

wary cloak
#

That is where the current project is stucked but

#

Because of the rfid

#

Because I successfully

#

Obtained the password from the user and compare it to another

#

Well if there's a function that would help like allowing use to write a string or give back a char array and we pass it as a parameters how many letter we want to write

#

That could help and sound useful

#

Or it could be not necessary enough for me it sounds really cool but what do you think?

coral geyser
#

put all the methods you want

wary cloak
#

Should we call it..

#

getCharArray?

#

Btw it's likely the two above would call getKey to do the dirty job and then add to it

coral geyser
#

make sure the types make sense

wary cloak
#

So the actually tricky thing is to do getKey

wary cloak
coral geyser
#

for the functions, what they take and what the return

wary cloak
#

Well for what they return that's easy

#

First two return a char and last one a char array

#

... Tho..

#

Since it's of unknown size actually a vector ferrisHmm

#
pub fn getKey() -> char {
        todo!()
    }

    pub fn waitForKey() -> char {
        todo!()
    }

    pub fn getCharArray() -> Vec<char> {
        todo!()
    }
#

And about receiving

coral geyser
#

do you have Vec without std?

wary cloak
#

An instance of -

wary cloak
#

I mean it showed me no error so I ain't sure..

coral geyser
#

?

wary cloak
#

No, that error because of unused serial

#

Warning*

#

So since there's no error we are fine with vectors..?

coral geyser
#

if it's not a module you won't get errors for it

wary cloak
#

Oh

#

...

#

It was better when I didn't import as a mod and it didn't have +9 errors(?

#
error[E0412]: cannot find type `matrix` in this scope
  --> src\Keypad.rs:4:13
   |
4  |     matrix: matrix
   |             ^^^^^^ help: a type alias with a similar name exists: `Matrix`
...
11 | type Matrix = [[char; 4]; 4];
   | ----------------------------- similarly named type alias `Matrix` defined here

error[E0412]: cannot find type `Pin` in this scope
 --> src\Keypad.rs:7:20
  |
7 | type ColumnPins = [Pin<OpenDrain, Dynamic>; 4];
  |                    ^^^ not found in this scope
  |
help: consider importing one of these items
  |
1 | use arduino_hal::port::Pin;
  |
1 | use core::pin::Pin;
  |

error[E0412]: cannot find type `OpenDrain` in this scope
 --> src\Keypad.rs:7:24
  |
7 | type ColumnPins = [Pin<OpenDrain, Dynamic>; 4];
  |                        ^^^^^^^^^ not found in this scope
  |
help: consider importing this struct
  |
1 | use arduino_hal::port::mode::OpenDrain;
  |

error[E0412]: cannot find type `Dynamic` in this scope
 --> src\Keypad.rs:7:35
  |
7 | type ColumnPins = [Pin<OpenDrain, Dynamic>; 4];
  |                -                  ^^^^^^^ not found in this scope
  |                |
  |                help: you might be missing a type parameter: `<Dynamic>`

error[E0412]: cannot find type `Pin` in this scope
 --> src\Keypad.rs:9:17
  |
9 | type RowPins = [Pin<Input<PullUp>, Dynamic>; 4];
  |                 ^^^ not found in this scope
  |
help: consider importing one of these items
  |
1 | use arduino_hal::port::Pin;
  |
1 | use core::pin::Pin;
  |

error[E0412]: cannot find type `Input` in this scope
 --> src\Keypad.rs:9:21
  |
9 | type RowPins = [Pin<Input<PullUp>, Dynamic>; 4];
  |                     ^^^^^ not found in this scope
  |
help: consider importing this struct
  |
1 | use arduino_hal::port::mode::Input;
  |
#
error[E0412]: cannot find type `PullUp` in this scope
 --> src\Keypad.rs:9:27
  |
9 | type RowPins = [Pin<Input<PullUp>, Dynamic>; 4];
  |                           ^^^^^^ not found in this scope
  |
help: consider importing this struct
  |
1 | use arduino_hal::port::mode::PullUp;
  |

error[E0412]: cannot find type `Dynamic` in this scope
 --> src\Keypad.rs:9:36
  |
9 | type RowPins = [Pin<Input<PullUp>, Dynamic>; 4];
  |             -                      ^^^^^^^ not found in this scope
  |             |
  |             help: you might be missing a type parameter: `<Dynamic>`

error[E0425]: cannot find value `rows` in this scope
  --> src\Keypad.rs:16:13
   |
16 |             rows,
   |             ^^^^
   |             |
   |             a field by this name exists in `Self`
   |             help: a local variable with a similar name exists: `row`

error[E0425]: cannot find value `columns` in this scope
  --> src\Keypad.rs:17:13
   |
17 |             columns,
   |             ^^^^^^^
   |             |
   |             a field by this name exists in `Self`
   |             help: a local variable with a similar name exists: `column`

error[E0412]: cannot find type `Vec` in this scope
  --> src\Keypad.rs:30:30
   |
30 |     pub fn getCharArray() -> Vec<char> {
   |                              ^^^ not found in this scope

Some errors have detailed explanations: E0412, E0425.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `keypad` due to 11 previous errors
#

Ok the first I forgot the capital

#

About Matrix, what do we call it then?

coral geyser
wary cloak
#

it says there it already exist one called that

coral geyser
wary cloak
#

oh

#

so what about the others

#

use arduino_hal::port::Pin;
|
1 | use core::pin::Pin;

#

which of the two i need?

coral geyser
#

use arduino_hal::port::Pin;

#

considering that is what we have been looking at the docs for

wary cloak
#

what do i return in getCharArray? how do i do dibamic size arrays without vec, is malloc here a thing?

coral geyser
#

do you need it to be dynamic?

wary cloak
#

I want getCharArray to do the following

#

I want you to be able to write more than one char at a time and that it return all those characters as a char array , not a string because with a char array I can compare it with another index by index so when I do this password thing is going to be reaaaally useful

#

And I wanted to take as a parameter an interger to say

#

Ok I want a char array of size 5 because that how many characters long is the password

#

So you are available to write as much as you want

coral geyser
#

what if you set a max length of the password and use an array of that length?

wary cloak
#

Well that works too

#

So how do I say I give back a char array? Because about the max that's something of the implementation so I would see that later

coral geyser
#

how about ```
fn get_chars(&mut self, buffer: &mut [char]) -> usize {

}

wary cloak
#

eh..

#

I'm kind of confused

#

First what was usize?

coral geyser
#

usize is for counting things

wary cloak
#

Because for example that isn't giving me back a char array, and it's asking me a char array and I want to make one not ask for one so I don't understand at all

coral geyser
#

it's the size of the memory space

wary cloak
#

So..

#

Usize tells me the memory space something needs?

coral geyser
#

?eval 1usize

#

Ferris !!!

wary cloak
coral geyser
#

its just a number

wary cloak
#

And that number is the number of bytes of memory needed for a certain variable?

coral geyser
#

no

wary cloak
#

Then idk what it is but

#

Why are you return that and not a char array as the idea was?

#

Returning*

coral geyser
#

the types of numbers

wary cloak
#

Eh I guess so, signed and usigned ints that have different ranges of numbers they can cover

coral geyser
wary cloak
#

So why not type just for example u16?

coral geyser
wary cloak
#

It's weird that they are the same but aren't used for the same-

coral geyser
wary cloak
coral geyser
wary cloak
#

So it expectes to be have a limit size of for example u32?

coral geyser
#

we stuff them in buffer

wary cloak
#

And why are we giving a char array as a parameter if I want the char array to be created there and give it back?

wary cloak
coral geyser
#

then return how many the user typed

wary cloak
#

But why would I want to return how many he typed if that's not data I'm interested in?

coral geyser
wary cloak
#

Oh wait so.

#

My function getCharArray

#

Would recieve as a parameter a buffer to store what I write when calling it?

#

And also I was going to say that all functions would need to recieve the instance of my struct that has the relevant data but now that I think about that would be with a mutable reference to self so that's fine I understand that very first part

wary cloak
#

The only thing I want

#

Is to write my characters and have all of them in a char array

#

How many, I don't care ig

coral geyser
wary cloak
#

So you say to also compare the lengths of the passwords?

coral geyser
wary cloak
#

Then what is it

#

I know you can't return a char array I tried

coral geyser
#

so you know how long the actual password is

wary cloak
#

But that's what I want to do

wary cloak
#

Oh

#

It return the size

#

So I can compare it to the maximum size I established

#

Right?

coral geyser
#

sorry, we went into overtime in my rocket league match, the size is needed because say buffer has length 15 chars. And the user types in 4 chars for the password. You need to know that the password in the buffer is only 4 of the 15 chars

#

Unless the password never changes

wary cloak
#

No need to apologize

#

Say I understand but

#

Oh

#

I understand

#

Since I borrow a mutable reference to buffer

#

By calling the function the buffer would have what I write to it

#

Ooh

#

Well so

#

We know the signature of this function now for the others

#

I think the only needed parameter would be an instance to hour struct that has all the important data, aka, a mutable reference to self, do you agree?

coral geyser
#

sure

wary cloak
#

Ok now I will send the remaining errors

#
Checking keypad v0.1.0 (C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\keypad)
error[E0412]: cannot find type `Dynamic` in this scope
 --> src\Keypad.rs:9:35
  |
9 | type ColumnPins = [Pin<OpenDrain, Dynamic>; 4];
  |                -                  ^^^^^^^ not found in this scope
  |                |
  |                help: you might be missing a type parameter: `<Dynamic>`

error[E0412]: cannot find type `Dynamic` in this scope
  --> src\Keypad.rs:11:36
   |
11 | type RowPins = [Pin<Input<PullUp>, Dynamic>; 4];
   |             -                      ^^^^^^^ not found in this scope
   |             |
   |             help: you might be missing a type parameter: `<Dynamic>`

error[E0425]: cannot find value `rows` in this scope
  --> src\Keypad.rs:18:13
   |
18 |             rows,
   |             ^^^^
   |             |
   |             a field by this name exists in `Self`
   |             help: a local variable with a similar name exists: `row`

error[E0425]: cannot find value `columns` in this scope
  --> src\Keypad.rs:19:13
   |
19 |             columns,
   |             ^^^^^^^
   |             |
   |             a field by this name exists in `Self`
   |             help: a local variable with a similar name exists: `column`

Some errors have detailed explanations: E0412, E0425.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `keypad` due to 4 previous errors
coral geyser
#

you need to add a use ... for Dynamic

wary cloak
#

What use exactly?

#

I thought it would be in mode like that other but it wasn't

coral geyser
#

search in the docs for Dynamic

wary cloak
#

Mmm

#

It seems it isn't in pins

#

Neither in modes

#

Mode*

#

Ah there you are bastard

#

So..

#

use atmega_hal::port::Dynamic

#

?

coral geyser
#

yep

wary cloak
#

And what about the other errors?

coral geyser
coral geyser
wary cloak
#

If I put row and column

#

It says no such field

coral geyser
#

rows: row

wary cloak
#

?

coral geyser
# wary cloak ?

in the struct you called it rows, in the function you called it row

wary cloak
#

And also the import failed

wary cloak
#

Because row says no such field

#

Rows says

#

Cannot find value in this scope

coral geyser
wary cloak
#

It worked

#
error[E0425]: cannot find value `rows` in this scope
  --> src\Keypad.rs:19:13
   |
19 |             rows,
   |             ^^^^
   |             |
   |             a field by this name exists in `Self`
   |             help: a local variable with a similar name exists: `row`

error[E0425]: cannot find value `columns` in this scope
  --> src\Keypad.rs:20:13
   |
20 |             columns,
   |             ^^^^^^^
   |             |
   |             a field by this name exists in `Self`
   |             help: a local variable with a similar name exists: `column`

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

only this left

coral geyser
wary cloak
#

That one?

#

I don't understand why but ok

coral geyser
wary cloak
#

But that'st the name of the function parameter

#

Anyways now that everything works

#

We have the last more or less complicated task

#

Making the getKey function

coral geyser
wary cloak
#

We know the logic and there's my C example but my C example do it another way

#

So we will see how to do that function

#

Then waitForKey would call getKey inside but do it so it blocks

#

An getCharArray call it multiple times or smth and store the chars it receives

#

The point is, this is the last "key" Part

#

So how do we do it?

coral geyser
#

how about we add 2 helper functions

wary cloak
#

What were helper functions?

coral geyser
#

one to enable one of the columns and one to read a row

#

actually, doing it as one function will probably work better

wary cloak
#

Like I did in my C code?

coral geyser
wary cloak
#

Oh I see

coral geyser
#
fn check_row_col(&mut self, row: usize, col: usize) -> bool {
  ...
}
wary cloak
#

Why row and col of usize here?

#

And a bool to true if it finds a match?

coral geyser
#

because self.rows[row] can work nicely without casts

wary cloak
#

and what's inside the array rows is usize?

coral geyser
wary cloak
#

I thought they were the pins(?

coral geyser
#

we index with a number

#

self.rows[0], self.rows[1], ...

wary cloak
coral geyser
#

yep

wary cloak
coral geyser
wary cloak
#

Oh I did them like in C++ sorry (?

#

Ok done

#

What do we write inside the new check function?

coral geyser
#

whichever col is

wary cloak
#

I thought we wouod start with an iterator or for

coral geyser
#

and make sure the rest are high

wary cloak
#

And then inside the for turn that one and then the other in the next iteration

#

Would"

coral geyser
wary cloak
#

...

#

Explain it to me I understand it a 70% or so

coral geyser
wary cloak
#

So I would be the current pin

#

So like for pin 1,2,3,4 (example ) in

coral geyser
#

yep

wary cloak
#

Self.cols you wanted to say self.columns?

coral geyser
#

oh yeah

wary cloak
#

Turn it into an iterator so it is iterable

#

But way a mutable one?

#

Why*

coral geyser
#

those mutate the pin

wary cloak
#

Oh

#

And enumerate if I remember correctly..

#

Gave back a touple with the index and element at said index?

coral geyser
#

yep

wary cloak
#

Which is what you are iterating through so it makes sense

#

So if the current iteration of the loop is equal to the col sended set it high and the rest set them low

#

I understand

#

Ok so now we have set the col sended to high and the rest to low

#

I guess we will then in getKey

coral geyser
wary cloak
#

Call this function in a for loop to iterate to each posible row in a column and then the next column and so

wary cloak
wary cloak
#

How do we check the row?

coral geyser
wary cloak
#

Remember me

#

Why row needed to be low

#

I remember column

#

If low was disconnected

#

And if high it was 0

#

And row..

#

It had 5v by default..

coral geyser
#

row is high by default

wary cloak
#

Oh

coral geyser
#

it goes low when connected to the column we set to low

wary cloak
#

So pressing it is low

coral geyser
#

yep

wary cloak
#

Tho we are asking there for what pin? All of them?

coral geyser
#

we don't need to check the others

wary cloak
#

Oh yeah

#

So

#

I pass a certain col and row

#

I guarantee only the col I pass is high by setting it in any case

#

And I ask if the row I send is low for that col, right?

coral geyser
#

yep

wary cloak
#

And you said I would only see a 0, low, not when I press it but rather when I press it and also it matches with the col?

coral geyser
#

yep

#

because it only goes low if it gets connected to ground

#

which only the one output set to low can do

wary cloak
#

And it's ground because it's 0v?

coral geyser
#

yep

wary cloak
#

But also the other thing would be 0v

coral geyser
#

ground by definition is 0v

wary cloak
#

It's like two ground or smth

#

So now we go to get key where we would basically do a for loop using this function?

coral geyser
wary cloak
#

That explains why it works even tho the 2 are 0 volts?

coral geyser
coral geyser
wary cloak
#

Oh I am supposed to know but you know supposed even tho I still use them when I learnt about them it was pandemic

#

So I couldn't say if I know enough

wary cloak
#

Ok then let's see

#

Since the function waits for a usize

#

I pass as a parameter the index?

coral geyser
wary cloak
#
pub fn get_key(&mut self)  {
        for (col, pin) in self.columns.iter().enumerate() {
            for (row, pin) in self.rows.iter().enumerate() {
                if self.check_row_col(row, col) == true {
                    return 
                }
            }
        }
    }
#

Two issues

#

First

#

Idk how to return

#

The key pressed

#

...

#

Mmm..

#

wait

#

I had an idea

#

Why not in matrix

#

Instead of 4,4

#

Do

#

Rows columns

#

So

coral geyser
wary cloak
#

I could call the matrix at the current row and col

wary cloak
coral geyser
wary cloak
#

If it works as you said forget it(?

coral geyser
#

it should work as is

wary cloak
coral geyser
# wary cloak

add a ; after the return and the continue is wrong

wary cloak
#

The error is the same

coral geyser
# wary cloak

and then at the end of the function you need to return a default char

#

or .... use Option<char> ferrisButGrimacing

wary cloak
#

So it could return none if it never finds one

coral geyser
#

yep

wary cloak
#

Still

coral geyser
coral geyser
wary cloak
wary cloak
coral geyser
wary cloak
#

If it doesn't match

#

Ask for the next

coral geyser
coral geyser
wary cloak
#

And when it's done asking the rows then it goes to the next column iteration

wary cloak
coral geyser
#

okay it's not wrong, just not needed

coral geyser
#

if ... {
...
}

#

behaves the same way

wary cloak
#

Anyways

#

You are right

#

Last issue

#

Borrow checker

#

Maybe I would need to use a smart pointer

#

But lemme run cargo check first

#
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
  --> src\Keypad.rs:28:20
   |
26 |         for (col, pin) in self.columns.iter().enumerate() {
   |                           -------------------------------
   |                           |
   |                           immutable borrow occurs here
   |                           immutable borrow later used here
27 |             for (row, pin) in self.rows.iter().enumerate() {
28 |                 if self.check_row_col(row, col) == true {
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.
warning: `keypad` (bin "keypad") generated 4 warnings
error: could not compile `keypad` due to previous error; 4 warnings emitted
coral geyser
#
for col in 0..self.columns.len() {
  for row in 0..self.rows.len() {
    ...
  }
}
wary cloak
#

Can you so len in columns and rows?

#

Now that I think about it

#

They are an array

#

So yeah

#

Dooone

#

So next wait_for_key

#

Can we easily just make something blockable?

coral geyser
#
loop {
  if let Some(key) = self.get_key() {
    return key;
  }
}
wary cloak
#

I mean I thought we were using nb::block

#

But I think that also works

coral geyser
wary cloak
#

Nah if it's not needed

#

Well finally only one method left

#

get_char_array

#

Tho two quick questiona first

#

Do you know what firmware is? i heard is software that operates ok hardware or modifies hardware or smth like that, like drivers, but you know seemed like embedded development was also that

coral geyser
wary cloak
#

So my definition is correct?

coral geyser
#

firmware is usually characterized by being indirectly influenced by a user. In other words, its software that just makes hardware do stuff

wary cloak
#

And also

coral geyser
#

its also usually unchangeable or hard to change

wary cloak
#

What else so you know to make in rust aside from embedded development? Apps with yew? Web dev with tauri, dino or webAssembly?

#

do you*

coral geyser
#

You can use Rust for basically anything you want, I have done all the above in some form before

#

Games is a growing one

wary cloak
#

Because you know since embedded development is kinda hard to do as hobby, cheap, and stuff it's like I would have nothing else to do with rust , after finishing the original project and this re write the idea was starting my adventure to learn C++ to a decent extent while finishing my python course and Django project, when all of that is settle on wanna finally dive into the web development world and learn HTML, CSS and JS, because they seems base knowledge nowadays, for example when I saw the real time chat app with rust with I thought hey interesting it used them

#

So I thought well I could in that future use rust as my backend

#

Be it for webs or apps

#

I want to use rust and that's the only other idea I have (?

#

And also..

#

To be fair I don't know for sure if I would use rust embedded again until it grows an ecosystem good enough ig, or I should see

#

So well I wanted to know of someone who also knew

#

Is it easier or harder than this web development?

#

At least the rust ecosystem there should be a lot bigger

coral geyser
wary cloak
#

Oh ok

#

Having said that

#

How so we begin the get_char-
_array function?

#

I guess we could

#

Enter a for loop for the len of the buffer

coral geyser
#

I need to go to bed 💤

wary cloak
#

And add to the index i so it changes which each iteration the result of calling getKey

wary cloak
#

I will do maybe a small prototype or smth (maybe not) and leave it here

#
pub fn get_char_array(&mut self, buffer: &mut [char]) -> usize {
        for i in 0..buffer.len() {
            if let Some(key) = self.get_key() {
                buffer[i] = key;
            }
        }

        return buffer.len()
    }
#

More or less that

#

Idk if I have to deal with /0 here

#

I tried to do

buffer[i] = '/0'

Below for loop but it didn't let me do it so

#

And also I know I'm not properly giving back the len of the actual used buffer and all that but this is kinda prototype to see how to better this later

old mango
#

Btw it's \0, not /0, although idk the api requires NUL termination or no

wary cloak
#

Well I'm used to the C way that all strings ends with the end string character therefore char arrays too

#

So idk if here I have to mark the end of the string with said character or not

wary cloak
#

Good afternoon @coral geyser are you available?

coral geyser
#

yep

wary cloak
#

Ok then today likely we can finish this project

wary cloak
#

But for the time being, is it fine for now?

coral geyser
#

because get_key doesn't wait

wary cloak
#

I didn't understand that at all the idea was for it to start the loop, click get key, if it's the some variant and to the current index them move to the next and you know

#

And then return buffer.len() just for the compiler not to shout at me

coral geyser
#

but you need to wait for no key being pressed between checking for the key pressed

wary cloak
#

Would the be fixed by making the exact same thing but with wait for key without the need for a if let.

#

*?

coral geyser
#

otherwise you will just get something like
aaaaaaaaaaaaaaaaaaaaaaa

coral geyser
wary cloak
#

So I replace get key with wait for key leaving the if let as it is?

#

Because

#

Wait for key return a char not an option char

coral geyser
# wary cloak So I replace get key with wait for key leaving the if let as it is?

we need something like

let mut index = 0;
loop {
  match self.get_key() {
    None => { /* no key pressed just check again */ }
    Some('a') => {
      // enter key pressed (here I use 'a' for enter)
      // we don't write the char to the buffer and return what we have written
      return index;
    }
    Some(key) => {
      // put key in the buffer
      buffer[index] = key;
      // move to the next char in the buffer
      index += 1;

      // check if we reached the end of the buffer
      if index == buffer.len() {
        return index;
      }
      
      // wait for key to be not pressed
      while let Some(_) = self.get_key() {}
    }
  }
}
wary cloak
#

I didn't understand at all(?

#

Why are we using a loop instead of a for?

coral geyser
wary cloak
#

So we will tell him that he can write as much as he wants and then use a key to finish the loop?

coral geyser
#

yep

#

though we probably want to stop it before the user writes more than the size of buffer

wary cloak
#

So we have a mutable variable index to know how long is the array and also

#

For indexing

coral geyser
# wary cloak Why are we using a loop instead of a for?
for index in 0..buffer.len() {
  match self.get_key() {
    None => { /* no key pressed just check again */ }
    Some(key) => {
      // put key in the buffer
      buffer[index] = key;
      
      // wait for key to be not pressed
      while let Some(_) = self.get_key() {}
    }
  }
}

would be the version for a fixed input size, aka the user always has to type in the amount buffer expects

wary cloak
#

So we use a loop so he's not forced to write a set amount nor less neither more?

coral geyser
wary cloak
#

Now I don't understand the first match so.

coral geyser
wary cloak
#

We call get for key and match it to the none variant and some variant

#

With an specific key

#

So if there's nothing pressed yet

#

Just keep going and asking

#

But if the specific key is presses end the loop and return the index so we know how long is the char array

#

Oh they are from the same match

#

I get it now

coral geyser
#

maybe we should add

// wait for key to be not pressed
while let Some(_) = self.get_key() {}

to wait for key

#

that would simplify this somewhat and help in other spots

wary cloak
#

And if another key is pressed it would be bind to "key" and stored in the current index of the buffer, then b
Index+1, and of that index is already the length of the buffer we go back

#

Now I just don't understand the last part of while let

#

Let me see if I understand

#

While the Some variant isn't an underscore (none I would suppose) it will keep going, since it's a while it will stay there and it needs a {}

#

It's that correct?

coral geyser
wary cloak
#

Then I don't understand how that line works

#

How does that waits until nothing else is pressed

#

Wait*

coral geyser
wary cloak
#

none

coral geyser
#

Does None match Some(_)?

wary cloak
#

Eh I guess so but that also matches any other pressed key

#

Why not ask for None?

coral geyser
wary cloak
#

But I want to be able to understand the one above first

coral geyser
wary cloak
#

Oh so

#

If whatever key is pressed

#

It continues

#

I don't care which key

#

That's why _

#

But when none is there it won't match and I know it's not pressed

#

Excellent

#

Now..

coral geyser
# wary cloak Explain this (?

matches!() takes a value (self.get_key()) and checks if it matches the pattern (None) if it does match it returns true

wary cloak
#

So the other ! It's so that when it return true it's false and it breaks the loop

#

Both of them are cool so idk which one to use..

#

Which one you think is cooler or you prefer?

coral geyser
wary cloak
#

Oh ok

#

So here it's the function up until now

#
pub fn get_char_array(&mut self, buffer: &mut [char]) -> usize {
        let mut index = 0;
        loop {
            match self.get_key() {
                None => { /* no key pressed just check again */ }
                Some('#') => {
      // enter key pressed (here I use 'a' for enter)
      // we don't write the char to the buffer and return what we have written
                return index;
    }
                Some(key) => {
      // put key in the buffer
                    buffer[index] = key;
      // move to the next char in the buffer
                    index += 1;

      // check if we reached the end of the buffer
                    if index == buffer.len() {
                        return index;
                }
      // wait for key to be not pressed
                    while let Some(_) = self.get_key() {}
            }
        }
    }
}
#

Is it done?

coral geyser
#

That will make wait for key behave better

wary cloak
#
pub fn wait_for_Key(&mut self) -> char {
        loop {
            if let Some(key) = self.get_key() {
                return key;
            }
        }
    }
#

In which part?

wary cloak
coral geyser
wary cloak
coral geyser
wary cloak
#

Tho I don't get why is it needed

coral geyser
#

this will make wait for key wait for a single press then release

wary cloak
#

So we aren't only dealing which short circuit but also

#

"Anti-rebote"idk how you call that in English

coral geyser
#

or debounce

wary cloak
#

How did you actually write the delay?

coral geyser
wary cloak
#

That