#Arduino Help
1 messages · Page 2 of 1
So the pins macro from the library take the "database" As an argument to store the available pins, right?
yep
well get the pins
But I didn't understand at all yet what's stored in dp
What does the pheripheral method do
Because to a microcontroller a pin is just a specific spot in memory has a 0 or a 1
That has to do with how this is a hardware abstraction library. It is abstract over all the avr microcontrollers
So like how a Arduino Uno has less stuff than a Mega the Peripherals struct knows what exists
And it can be used by other code to know what it can do
Oh so pheripheral is a struck
yep, it looks like https://rahix.github.io/avr-hal/src/avr_device/devices/atmega328p/mod.rs.html#489
Source of the Rust file /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/avr-device-0.3.4/src/devices/atmega328p/mod.rs.
And it stores in what Micro components ate connected to see what it can and cannot do?
And what does the take method on the pheripheral struct do?
It says we want to take ownership of all the peripherals
And it can fail for any reason so it returns a result type we now it won't so me call unwrap?
Like we don't want 2 Pin5 structs that think they can both control pin 5 at the same time
It returns an Option because we may have already taken it before
Oh
let dp = arduino_hal::Peripherals::take().unwrap();
let dp2 = arduino_hal::Peripherals::take().unwrap();
this would be bad
Makes sense :0
The pins macro generates a struct for all pins available?
Now code can own specific parts of the microcontroller
yep
So the dp and pins parts is something I'll always do to right?
Likely, you can bypass them if you need to access some of the pins the general one doesn't have
Like the Mega has a lot of pins not in the general set
But wouldn't I need the dp for a lot of stuff?
yes you will almost always need the dp
ah, because we want to blink it. and to do that we need to change it's state from on to off and back
Because it will change from 1 to 0 all the time?
yep
yep all the usable ones on a Mega board are available https://github.com/Rahix/avr-hal/blob/main/arduino-hal/src/port/mega2560.rs
The d is for digital
There are also the analog ones with "a"
So we create the mutable variable led, access the pin 13 from the pins variable that stored whatever was the result of calling the macro and called the method from the pin 13 struct into_output to say to the program this pin is an output?
yep, the into_output is like the pin mode in Arduino, but it's enforced by the type system
So we have a variable that stores a pin and wherever is an input or an output, it will be mutable and have the name of our pheripheral
Right?
So we will always do this also like doing pin mode
yep
Tho there's another why to set pins to output or inputs that was all that PORTB stuff and so
That idk if it's supported here
We now have set digital pin 13 to output and are ready to turn it on and off
But anyways that wouke finish the setup part that it's main and we enter the loop part just like Arduino
Now I understand
Input vs output changes how the hardware in the microcontroller is setup so it can either send electricity or receive it
Why you said that about the setup part executing one now it makes sense
Yep now we start a loop and keep toggling the pin and waiting
What I was asking if you can like in Arduino do I think it was something like..
DDRD = 0xF0
oh yeah you can if you have to
switch the state of the pin to the opposite, on -> off, off -> on
yep
Which in this case would turn the led either on or off
there is also set_high() set_low()
yep
And I say to delay here we call the delay_ms function from the library and pass the milliseconds it calls my attention the ms, does it support delays in other ways?
Like in seconds?
For example yes
Because it's called delay in ms
And not just delay
Maybe there's delay_sc
Or smth
it has ms and us
U for micro?
yep
Ok last question
I was wondering
For when it's just a led that uses one pin to control it's fine but
I wonder when we use the RFID for example what are we calling our variables (?
Just had the thought
like when you have many pins?
And btw this is surprisingly very familiar I mean it's totally how I would imagine it to be, just like programming C++ in Arduino but is rust in VS code the level of abstraction is the same almost, I thought it was gonna be lower level, or is it just because the simplicity of this program that it's almost as easy as Arduino?
Yeah
You can store them in a struct
pub struct ShiftRegister<Data, Clock, Latch> {
data: Pin<Output, Data>,
clock: Pin<Output, Clock>,
latch: Pin<Output, Latch>,
}
https://gitlab.com/konnorandrews/8-bit-computer/-/blob/main/eeprom/programmer/src/shift.rs#L4
Oh
And because we own the pins we know no other safe code will touch them
.
It calls my attention how not that hard it was
The part you may find lower is if there isn't a library for something you want to talk to
Yeah that worries me..
But otherwise it would just like what I've been doing but in rust?
Because that's so fucking cook
Also before we end, if you need docs for the libraries involved use cargo doc --open to generate local ones. The online ones are setup for the Arduino Uno
Because it would be even more comfortable because I'm in a language that I understand a bit more, that has cooler tools like iterators and that has compile error messages that make me confident to try
The people that work on this have done good to make it as friendly as possible without loosing the control you sometimes need
But there's a small concern
The only bad part
Is that I won't be able to work the code at school when I have the subject
Because you literally have to install so many things and of course the computers there don't have it
Because they don't even know rust
We have Vs code and Arduino ofc
But why would they have all the rust tools(?
hmm, yeah that is an issue
And I ain't that garbage of a computer there
It would be a pain
There's one person that does do that
Which is..
Interesting
Yeah because I want to upload the code live to test it or if a dumbass presses reset
And also show the code and ofc be able to work on it
You don't need to reprogram it if you turn it off 
Do you think there's any solution aside from taking my computer there?
You could put a rustc on a usb drive
Because also it may be kinda snobbish but.. I wanna show them what I use and if interested teach them
Buy an USB and save all that million filed I downloaded on an USB?
Files*
Yeah, though the one part you can't is the microsoft build tools
Idk how that works but that would make that just by plugin the USB I will have all the files so I could work just like home? (But likely with more ram)
which I doubt they have on those machines
yeah, you can tell rustup to keep everything on a USB drive
Ok we'll do that but later I mean
Microsoft be stupid
I don't have classes until Monday
And also I don't have that subject until Wednesday
Which is the only day I have it
So we have time
So the USB plan won't work?
Actually, you may not need the build tools if you prep it on your computer before hand
As the arduino building doesn't need it
But I wanna code in school too (or I didn't understand what you said)
Like
Preparing the folder the cargo build
I think you can do it. I can try it on my machine later if you want
And then just write the code in Vs code and hit run since its already built
I would thank you
Last question and I'll let you finally count sheeps
yep, you need the microsoft build tools if you build for windows, but you are building for Arduino 
Out of curiosity
What's next? What are we doing tomorrow? Learning how to control the LCD which would be the first component?
It's either that or idk what else could be
Yeah then just like I did in Arduino
LCD
Matriciak keyboard
Both together
Relays with the stuff idk how to spell
RFID feature by feature
As long as we have a library it shouldn't take long
I will probably busy for some of tomorrow not sure when, a friend comes back from a trip and we have a Starcraft 2 session planned
But if we don't.. That's where it would get complicated
Np actually I usually do this as night as you see but tomorrow at my 20:00 I go somewhere actually if I go alone and know one takes me there, earlier
I did all of that excepting RFID in more or less a week
datasheet time 
My goal which I hope isn't unachievable
Is to have all but the RFID so, the basic functionality of the project, LCD, keyboard, relays activating at the right moment so on Wednesday when we test it in the actual thing like the thing we are building
See that it works in a real scenario
I wonder what's gonna be their face when I come and say
Hey,re Writting the project in another language because I felt like it (and because Cpp sucks)
And test 2 codes, the Arduino one and the rust one
So I'll upload both one at a time
Hope I get that on time
Anyways
Thank you very much for your kind support and knowledge
Good night
no problem, happy to help 

I'm off for another round
Hey, how do you look for libraries? (I won't accept GitHub as an answer)
Because the first step would be to find an LCD display library
Tho I have to leave soon but at least maybe we can find the library to have it hand for tomorrow
I'll be more specific
Is an LCD display with I2C 20x4
Idk if it will be a pain or not the fact that I use I2C
For me at least I just need four wires instead of like 8 of them and two of those for are GND and VCC
LCD I think is such a common component that there should be a dependency for it
Yay
Tho I haven't gone there either
Is there abstractions for other arquitectures like the AVR one we are using? Do you find it also in crates.io or in another place?
I love you rust community..
Well are there? (Honestly just because I want the raspberry Pi pico) and also..
I can't change the microcontroller now but
Do you know if it's a https://docs.rs/lcd/latest/lcd/ type lcd?
Library that implements low-level protocol to the Hitachi HD44780-compatible LCD device.
Would recommend me another microcontroller for a project like this or what would you had use?
Honestly I only now the LCD display 20x4 with I2C part the rest I have no clue tbh
That is a difficult question, but probably just an Uno
Is there any part or the micro component it could be written it?
Oh so an arduino still
I have them so 🤷♂️
Tho thanks to using the MEGA I have enough VCC and GND pins to test everything at once without using a breadboard
We could spend a few days looking at microcontrollers if you wanted to find the "best" one for the job
I thought you would came out with a weird microcontroller name I never heard about (?
Like the ESP something or really anything because I only barely now ESP, arduino ofc and raspberry Pi pico
In truth I would probably use an FPGA, because I like using them
So excepting if you need more memory or pins, really whatever works?
Yeah
Well how could I know the information you need to know about my LCD?
Because I was going to bought it only bit
But*
Who needs a microcontroller when you can just have a programmable circuit
It would have a part number on the back probably
A friend of mine offered for bought it in an electronic house near it's job so we wouldn't have to pay to send it our way
That?
It already has the I2C on it as you can see ofc
What's that?
Well it's basically that one or it's highly identical
Btw as I asked, it bothers having to work the I2C or it makes it easier?
Mainly because when I told you about the RFID using SPI you said is kinda easier but also harder
It's fine, I found https://github.com/wfraser/lcd-pcf8574 which you can base it off of. We just need to use the arduino_hal version of the i2c
Arduino_hal version of the I2C?
https://rahix.github.io/avr-hal/arduino_hal/i2c/index.html the repo above is for raspberry pi boards
API documentation for the Rust i2c mod in crate arduino_hal.
This crate ^ should do all the heaving lifting for actually controlling the lcd
You just need to tell it how to use the i2c device to talk to it
So the LCD part is abstracted but the I2C is on our part?
I hope it's not
So this dependency we handle it like any other by adding the name and version in the cargo toml file?
Tho which of the two
https://docs.rs/lcd/latest/lcd/ will be a dependancy the other is just for reference
Library that implements low-level protocol to the Hitachi HD44780-compatible LCD device.
And in which toml I add that?
And what version is?
So you know
I type " lcd = 0.8.0"
Or smth
Version 0.4.1
cargo.toml
Yep
Have you use it before?
Not this one, but it looks good
Next idk if it'll help but I thought I could show how the implementation was for the arduino under the library I used
At least to show what I want it to do
But there's let's say two version
First when I used it as it was, manually
But then I created a function for it (which took me some time)
That handled a lot of the stuff
Like automatically centering the message but only if I told it to or I could chose where it would begin
Tell me if it was too long the string I was pasing
And stuff
I actually even used an struct
Tho idk it'll actually help I thought it could serve as reference maybe
You can definitely use that as a base, but it's probably a good idea to get it so that the lcd library can talk to your display so you know it works
It's just for reference of the logic and steps let's say of course I don't want to call that code or anything I want to use only rust and it's tools
Let me look for it
Tho I think I could take the opportunity and
The lcd crate should be nicer to work with be use you can do things like this
?eval println!("{:^20}", 123);
123
()
Send the whole code for the base functionality of the project (LCD, keyboard, relay) because it's actually short, I'll show you the original version when I just learned how to use the libraries and the version with functions to avoid repetition
Automatic centering
Btw I did the automatic centering optional because there was text I wanted to start from the beginning and looked weird otherwise
Well let me look for it I also have to prepare to leave soon which it's a shame but I'll try to at least show you that before so we have everything to work with tomorrow
Ok
Ok this is first version using the librariea as they are
You'll see unnecessary repetition it was made like 2 months ago or so
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
const byte FILAS = 4;
const byte COLUMNAS = 4;
const char keys[FILAS][COLUMNAS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
const byte pinColumnas[COLUMNAS] = {22, 23, 24, 25};
const byte pinFilas[FILAS] = {26, 27, 28, 29};
Keypad keypad(makeKeymap(keys), pinFilas, pinColumnas, FILAS, COLUMNAS);
char tecla;
bool confirmacion=0;
void setup() {
pinMode(2, OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
lcd.init();
lcd.backlight();
}
void loop(){
do{
lcd.setCursor(3,0);
lcd.print("Elija una bebida");
lcd.setCursor(1,1);
lcd.print("1-Fernet con Coca");
lcd.setCursor(1,2);
lcd.print("2-Sex on the beach");
lcd.setCursor(1,3);
lcd.print("3-Agua");
tecla=keypad.waitForKey();
if(tecla=='1'){
confirmacion=1;
}
else if(tecla=='2'||tecla=='3'){
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Bebida");
lcd.setCursor(3,1);
lcd.print("No disponible");
confirmacion=0;
delay(1000);
}
else{
lcd.clear();
lcd.setCursor(3,0);
lcd.print("elija un");
lcd.setCursor(3,1);
lcd.print("valor valido");
confirmacion=0;
delay(1000);
}
} while(confirmacion!=1);
do{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Elija la intensidad");
lcd.setCursor(1,1);
lcd.print("1-Suave");
lcd.setCursor(1,2);
lcd.print("2-Medio");
lcd.setCursor(1,3);
lcd.print("3-Fuerte");
tecla=keypad.waitForKey();
if(tecla=='1'||tecla=='2'||tecla=='3'){
confirmacion=1;
}
else{
lcd.clear();
lcd.setCursor(3,0);
lcd.print("elija un");
lcd.setCursor(3,1);
lcd.print("valor valido");
confirmacion=0;
delay(1000);
}
} while(confirmacion!=1);
lcd.clear();
lcd.setCursor(3,1);
lcd.print("Preparando...");
lcd.cursor();
lcd.blink();
if(confirmacion==1){
switch(tecla){
case '1':
digitalWrite(5,HIGH);
delay(2000);
digitalWrite(5,LOW);
delay(1000);
digitalWrite(4,HIGH);
delay(4000);
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(5,HIGH);
delay(5000);
digitalWrite(5,LOW);
delay(1000);
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(5,HIGH);
delay(8000);
digitalWrite(5,LOW);
delay(1000);
digitalWrite(4,HIGH);
delay(2000);
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;
}
}
lcd.noCursor();
lcd.noBlink();
}
Pretty simple as is
Now I'll show you the last version improved with home made functions
Specially for that last switch statement
Ok here it is the last version
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#define PIN_ALCHOHOL 5
#define PIN_ACOMPANANTE1 4
#define PIN_ACOMPANANTE2 3
#define PIN_ACOMPANANTE3 2
struct PrintOptions {
String toPrint;
int pos;
};
const PrintOptions empty = {"", 0};
LiquidCrystal_I2C lcd(0x27, 20, 4);
const byte FILAS = 4;
const byte COLUMNAS = 4;
const char keys[FILAS][COLUMNAS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
const byte pinColumnas[COLUMNAS] = {22, 23, 24, 25};
const byte pinFilas[FILAS] = {26, 27, 28, 29};
Keypad keypad(makeKeymap(keys), pinFilas, pinColumnas, FILAS, COLUMNAS);
char tecla;
bool confirmacion=0;
void imprimirFila(byte posY, byte posX, String fila){
if(fila != ""){
byte caracteres_restantes = 20 - fila.length();
if(caracteres_restantes<0){
lcd.print("muy largo 1");
}
byte posicionX = posX == 'c'? (caracteres_restantes/2) : posX;
lcd.setCursor(posicionX,posY);
lcd.print(fila);
}
}
void imprimir(PrintOptions fila1 = empty, PrintOptions fila2 = empty, PrintOptions fila3 = empty, PrintOptions fila4 = empty) {
imprimirFila(0, fila1.pos, fila1.toPrint);
imprimirFila(1, fila2.pos, fila2.toPrint);
imprimirFila(2, fila3.pos, fila3.toPrint);
imprimirFila(3, fila4.pos, fila4.toPrint);
}
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);
}
void setup() {
pinMode(2, OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
lcd.init();
lcd.backlight();
}
void loop(){
do{
imprimir(
{ "Elija una bebida", 'c' },
{ "1-Fernet con Coca", 0 },
{ "2-Sex on the beach", 0 },
{ "3-Agua", 0 }
);
tecla=keypad.waitForKey();
if(tecla=='1'){
confirmacion=1;
}
else if(tecla=='2'||tecla=='3'){
lcd.clear();
imprimir(
{ "Bebida", 'c'},
{ "No Disponible", 'c'}
);
confirmacion=0;
delay(1000);
}
else{
lcd.clear();
imprimir(
{ "elija un", 'c'},
{ "valor valido", 'c'}
);
confirmacion=0;
delay(1000);
}
} while(confirmacion!=1);
do{
lcd.clear();
imprimir(
{ "Elija la intensidad", 'c'},
{ "1-Suave", 0},
{ "2-Medio", 0},
{ "3-Fuerte", 0}
);
tecla=keypad.waitForKey();
if(tecla=='1'||tecla=='2'||tecla=='3'){
confirmacion=1;
}
else{
lcd.clear();
imprimir(
{ "elija un", 'c'},
{ "valor valido", 'c'}
);
confirmacion=0;
delay(1000);
}
} while(confirmacion!=1);
lcd.clear();
imprimir(
empty,
{ "preparando...", 'c'}
);
lcd.cursor();
lcd.blink();
if(confirmacion==1){
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;
}
}
}
lcd.noCursor();
lcd.noBlink();
}
There it is
Looks good
The basic functionality of the project, LCD, Key board and relays
I have also a simulation if you need to see it in practice but that's up to you
And just for the record this is basically what I want to re write in rust first, ofc it's not all because there's the RFID missing but that's the most fundamental pillar of the project and the first goal
Ofc for now let's just focuse in the LCD part
Make the LCD go blink 
I would like to make it like the final version with a function like that, that makes it a lot easier to write whatever I want and it handles a lot of stuff without me having to repeat lcd.print, lcd.set cursor and so all the time
It already uses a struct so(?
I wonder just how different it'll be
Well I have like half an hour so let's see what can be done in that time let me be turning on my computer
No actually 20 minutes at best
Do I open vs code in the same folder as last time
Yep
So open the terminal CD'ing into it, using cargo new, CD'ing into it and calling . Code to open it in vs code?
What do we call the project?
Are we doing the full project in this or this folder with be for just making work the LCD and then we create another for each component?
(It's something I would do if)
Ig*
I would just use the one from before and build on it
This is where git would be nice 
No you can just use this one
We would work in git instead of vs code?
Or copy the avr-hal-template-main to a new folder so you don't have to set it all up again
I prefer doing one project for each component so I have it tidy and maybe I can call them in the final project or smth
With git you could save the state, and then come back in the future even if you changed files
Well you need the Cargo.toml and cargo/config.toml
I can just copy paste them in the new folder from the old one
Yep you can
Ok so..
You should probably go in the cargo.toml and rename the project
I run cargo new there when I stand in the terminal?
Here
Go one directory back
Oh ok
I don't think you want them inside each other
You can make a new folder to put them in
Where do I create the folder?
That works
Nope, we good
Sure
Ok I opened VS code let's make the set up
Mm it's weird
Literally nothing happened
I don't have any folder

Ignore the errors
But as you see
I did the usual
I'm in vs and..
Nothing
Well I went to open folder and opened it manually tho. . Weird
🤷 I thought you just put code no .
Windows
Well I will parallely open the one for yesterday and copy
Where do I create the other TOML file? Because last time I needed two and here it's one
You will replace/add to the one their and then copy over the .cargo/config.toml one
And you will need the json file for the mega
Add?
Well you could keep the [project] header and just add the rest of it
I wouldn't be understanding what to do
First
I'll go to the toml file in the other
Which had
This
And past it to the new project toml
Sorry I meant [package]
The .cargo/config.toml
^ same spot
So I create a new cargo.toml in there scr directory and paste that?
Because I don't remember where it was
Well you were right thing ended up being really complicated but well
I hope next time we can create a copy of another project to have the set up done
Actually how many other stuff I need to copy from the other file -
Isn't there a way to just copy all directories that are in vs code to the other new vs code project?
Right click directory, copy, right click other vs code paste 
^ 
Which folders do I need to copy?
I didn't understood-
Well tell which of all the folders I need to copy so when I come back even tho you'll probably be asleep I can set it all up for next time
Tho..
The .cargo/ one and the one with the json files in it forgot the name
Ok, it doesn't matter where?
Because seems like folder had a scope too or smth
Folders*
You just need to make this new folder look like the original, except for the target folder (cargo will make that one)
Ok I'mma try make it similar and when I'm done I'll send a picture
Now that you've seen what I want to re-write (well at least more than half of it) how hard do you think it would be to get it done?
I am unsure, but I think it's doable
How long do you think it could take?
I guess it's reduced to whether everything has libraries or if some things doesn't
Depends entirely on you, very hard to judge
Well as I said the first version the code I sent you prior took less that a week but
Maybe in rust it's harder? Or maybe some component doesn't have a library
What I would be hoping it's to do it for next weekend maybe but idk how is it
Next Wednesday if possible but maybe that's too little time
Not having a library is somewhat likely just because it's not as big of an ecosystem as Arduino
I'm willing to spend a lot of time on this myself
Yeah that worries me a little bit but it's also a bit exciting also, to learn that and so
But I don't like dragging other people down(?
My recommendation, done rely on it getting done in time
I didn't understand
Ah you wanted to say don't so, O should expect it to get done in that time?
Well I mean I guess I have more time that situations would merely be ideal
Ok I am able to continue now, since I have only 3 days left of holidays I will dedicate all time posible in this three days to give it a huge boost
Because after that it will be harder to dedicate it so much time
I had a random idea
I guess the answer's no but
Is there any scenario where you could you use multi threaded programming in embedded systems?
And I also wonder how much will it cost to do it in terms of memory
And I would ask the same for asynchronous programming but I have yet to research what's that
@dreamy trellis I just realized you are also here, interested in arduino rust programming?
Oh
Well if there was something you wanted to do with it you could buy one or the cheaper imitation ones since it's open source
sure
I recommend it, it's fun
Seeing your results irl
I heard people consider embedded programming the easiest.. Idk why but maybe just maybe they coould be right I'm not sure because I haven't done much else
i dont think thats quite true
Me neither
What's harder is the fact that you need to buy stuff, which could often be expensive
And it doesn't depend only on your code
If you want to do an actual thing you need to work with other stuff like PCBs, maybe wood, etc
@coral geyser are you available?
I've finally done the setup imma send the pictures to confirm if it's ok
The main function, both cargo toml files, the toolchain and the specs full of JSON
Well actually I forgot to this so I'll go do that
I just realized there are two dependencies sections. .
I'll put it in the normal dependencies and leave dependencies arduino hal alone
Tho I have an error I think by changing the name in the toml file in the package section from test to rust_lcd tho if it isn't that then no clue
you can run cargo check to get a better error message
It suddenly decided to be full of errors why does it do this to me-
Just for reference I changed the name back to test to make sure
error: Ensure that you are using an AVR target! You may need to change directories or pass a --target flag to cargo. See
https://github.com/Rahix/avr-device/pull/41 for more details.
--> src\main.rs:6:1
|
6 | #[arduino_hal::entry]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the attribute macro arduino_hal::entry (in Nightly builds, run with -Z macro-backtrace for more info)
error: could not compile test due to previous error
do you have the .cargo/config.toml and the json file that defines the target?
Yes as shown in the pictures above, I could send them again if it's more comfortable to you
the config.toml is in the wrong folder
Just because I don't trust myself with this I sent the photos of what I copied and where because maybe juusst maybe I have what I need but in the wrong place
Where do I place it?
in a folder named ".cargo"
folder inside src or just there?
in the same folder that src is in, but not in src
project
|- .cargo/
| |- config.toml
|- src/
|- main.rs
yep
Tho the error remains there
run cargo check
Btw is there everything I need there and in the right place or I have something else in the wrong place like maybe the specs and so
it looks right
The fact that it failed before wasn't because of me changing the name of test in package but this?
Yep
Ok then if it checks I'll change it again
do a ctrl + p and then "reload window"
Btw the lcd dependencie..
that should reset rust-analyzer
Dependenci*
Dependency*
Where like.. In the dependency section or the arduino hal dependency section
just the normal dependency section
It do be taking it's time to check
This like hitting compile instead of upload, right?
I guess it's building everything maybe
It finished it compiled
Tho ctrl p doesn't work and the error it's still there
i changed the name again and cargo check said this
error: failed to parse manifest at C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\rust_lcd\Cargo.toml
Caused by:
can't find test bin at src\bin\test.rs or src\bin\test\main.rs. Please specify bin.path if you want to use a non-default path.
sorry it's Ctrl+Shift+P
Oh you changed the binary name in the config
Ah
I had to change bin to?
No, seems it's not it, it failed again
Or maybe it's taking it's time to accept it?
I'll run ctrl shift p as you said
And then cargo check
The package name and binary name don't match now
So I should leave at test? Shouldn't we give it a proper name?
you can add path = "src/main.rs" to the [[bin]] section to manually set the file for it
you can also just set name = "rust_lcd" in the [[bin]] section
I did
Well seems the reload solve it
Ok so I guess finally it's all setup
I hope now I just copy from here knowing what and how and there's no more 30 minute setuping for actually doing something
How do we start?
OH COME ON
The same error appeared again
And it went away
Wtf goes on with rust analyzer
RA has issues when you change targets
It gets confused sometimes
I'll suppose it's finally fine so, how we start, the use keyboard to bring something into scope, the dp and pins stuff?
you are going to get the lcd working right?
first probably make sure this compiles and uploads to the board and blinks the LED
Oh sure
I have found the best way to do development is to be as close to a known working setup as possible so if something breaks you only have to check what you just changed
What do you mean a working setup?
Like no errors
It's already blinking (I hit reset before when I realized it was blinking without me writting Cargo run)
But
It said finished running and all but again said the thing about the serial port
Which is weird because
It's blinking anyways
remember it will start running whatever you last had on it when you plug it in
Ik that's why I hit reset before running cargo run
reset doesn't remove the program
Ah
It just restarts it
You should find the port it's connected to again
I think it was COM6 last time ?
When you program it the lights will flash rapidly and the cargo run command will land in the serial monitor
Here
yep, usually windows will keep the same port, but sometimes it changes
Yeah I saw an extra light flash rapidly and so
So yeah it works
So there's no way to erase a program but just override it?
The microcontroller will always be running something you could have a empty program loop {} that you put on it when you don't want it to do stuff
I think a good next step is to make a src/lcd.rs file to hold your LCD code
Next time at least I can get all this setup myself hopefully
Won't we code in main.rs?
It's good to work in modules so your code doesn't get to messy
We aren't using main or we are using it later?
Lcd it's gonna be our library crate or another binary crate?
It where be where you do stuff, but we need to setup some stuff first
So like extracting the logic from main and just calling the public api?
remember how we need to connect the lcd library up to the i2c communication? also you wanted to copy some of your custom lcd management code
It will just be a module mod lcd; (in main.rs)
okay we will use https://github.com/wfraser/lcd-pcf8574/blob/master/src/lib.rs as a template
What's a template?
so just copy over the code from it
We will follow the same structure as the code above, but make it specific for the Arduino Mega
This should be easier
It will end up being mostly from scratch
Done
No, I will
yep
I got it in main for some reason
oh it's just ```rust
mod lcd;
this defines the lcd.rs file do be a module
We don't need the #!... lines at the top on lcd.rs
so remove those
and we don't need any of the use lines except for use lcd::{Delay, Hardware};
we can't use the std ones because ... we don't have std 
we need the
use lcd::{Delay, Hardware};
one, we also don't have i2cdev as this isn't running linux
Bruh I thought you said
We don't need that one
" except for " 
Ok done
Did the double negative mess you up?
I may be just a little asleep
So now we need to find what "LinuxI2CDevice" needs to be replaced with
So basically as with the toml we are getting rid of everything not arduino mega specific first, aren't we?
in a terminal in vs code run cargo doc --open
yep
It's building stuff
you should get this in a web browser
Eventually
This will be the docs for all the dependencies of your project. Which you need because it will be specific for the Arduino Mega as we configured it to be
Btw what would be the code we copied? The actual library or smth?
Its an adapter between the lcd library and the linux i2c device
The lcd library expects you to have the lcd connected with 6 wires not i2c. So we just need to adapt it
So first we have the LCD library for normal lcd but we can't just work with that so me use a code that will help us with the I2C
It had errors and it didn't open anything-
error: cannot find macro `format` in this scope
--> src\lcd.rs:32:38
|
32 | dev: LinuxI2CDevice::new(format!("/dev/i2c-{}", bus), address)?,
| ^^^^^^
error[E0412]: cannot find type `LinuxI2CDevice` in this scope
--> src\lcd.rs:7:10
|
7 | dev: LinuxI2CDevice,
| ^^^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `Box` in this scope
--> src\lcd.rs:21:12
|
21 | Custom(Box<dyn FnMut(LinuxI2CError) + 'static>),
| ^^^ not found in this scope
error[E0412]: cannot find type `LinuxI2CError` in this scope
--> src\lcd.rs:21:26
|
13 | pub enum ErrorHandling {
| - help: you might be missing a type parameter: `<LinuxI2CError>`
...
21 | Custom(Box<dyn FnMut(LinuxI2CError) + 'static>),
| ^^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `LinuxI2CError` in this scope
--> src\lcd.rs:30:55
|
24 | impl Pcf8574 {
| - help: you might be missing a type parameter: `<LinuxI2CError>`
...
30 | pub fn new(bus: u8, address: u16) -> Result<Self, LinuxI2CError> {
| ^^^^^^^^^^^^^ not found in this scope
error: Compilation failed, aborting rustdoc
For more information about this error, try `rustc --explain E0412`.
error: could not document `rust_lcd`
oh, add --keep-going
And then a really long text
By default it won't let you if there are compilation errors with the code
actually just comment the mod lcd; in main.rs run the command then uncomment it
I should have had you open this first
Oh ok I was just typing the other stuff
cargo doc --open --keep-going
It opened
With the comment solution
Ok finally
Arduino hal then?
go to the i2c bus controller
The one we want is the bottom Type definition one (they are both the same)
Then why is it two of them? A mistake?
I think their docs config is slightly messed up. Some devices have multiple i2c so it's probably for that
Now click the I2c in that line
Alias wasn't it?
yep the mega i2c is a special case of the I2c struct
As you can see this looks like what we want right
So now going back to the lcd.rs file
Honestly
I get half of what we are doing rn
So we were looking for
The definition of the variable (or special instance of the I2C struct) that has all the I2C protocol information and for our specific microcontroller instead of using a whole other struct or stuff bigger than this?
yep, we need something to replace LinuxI2CDevice
Tho this one says for arduino uno
yeah thats what the example shows
in the lcd.rs file we can replace LinuxI2CDevice with arduino_hal::I2c in the struct definition
So basically this example code you found is on how someone used the I2C protocol with the library we are interested in but it was with Linux so we are replacing all the unnecessary stuff and changing all Linux to mega
exactly
super common in software development to find close to but not exactly what you need
Tho I guess this is another library or something because it has documentation and stuff but the base case is Linux ig tho it supports other stuff for you to change it
Ok now I think I more or less get what we are doing
You can also change the name of the struct Pcf8574 to something you prefer
yep
I guess Lcd with a capital L, what do you think?
sounds good
You can also update the doc comments (///) as we go so you remember stuff later
It will represent the connection to the Lcd
Ok so it's ok
So the comment above this struct originally is
/// Represents an LCD display attached via PCF8574 I2C expander. Use the traits in the [lcd]
/// crate to interact with it.
So I guess I would write
I just remembered that you will probably have a higher level struct that will be your custom LCD methods specific to the project
///This struct represents the LCD Microcomponent connections
I don't have anything else to say
Mmm
also, because we have basically direct control over the i2c hardware we don't need to worry about what to do if an error happens
So we don't need the on_err field of the struct or the ErrorHandling struct
The stuff your arduino code does
So I deleted the error handling enum and on_err field
Using underscores and that on struct names feels a bit ugly but
You could use
k now we get to
pub fn new(bus: u8, address: u16) -> Result<Self, LinuxI2CError> {
Ok(Self {
dev: LinuxI2CDevice::new(format!("/dev/i2c-{}", bus), address)?,
data: 0b0000_1000, // backlight on by default
on_err: ErrorHandling::None,
})
}
lcd_wires
LcdConnection ?
Sure
or the proper term in spanish
The doc comments are in Spanish but struct names I do them in English
Ok we get to the new function yeah
Oh
So now for this we don't have a bus or address, we will get the arduino_hal::I2c struct by doing
let mut i2c = arduino_hal::I2c::new(
dp.TWI,
pins.a4.into_pull_up_input(),
pins.a5.into_pull_up_input(),
50000,
);
(well close to)
I should change the name of the impl block
So I think ```rust
pub fn new(dev: arduino_hal::I2c) -> Self {
Self {
dev,
data: 0b0000_1000, // backlight on by default
}
}
should be good
Ok I'll copy that from here in it's place
But why wouke be the bus or adress and why won't we need it?
The 0b0000_1000 magic number is probably defined in the datasheet for that board on the back of the lcd
Because we will just do this ^
We have direct access to the hardware
And this library suppose we doesn't?
yep, on linux the OS may prevent you from connecting to the I2c bus
Ok time to change the doc comment
Oh so this is just because of Linux stuff ok I guess knowing that it's enough then
ok original comments
/// Create a new instance, using the Linux I2C interface for communication. bus is the number
/// of /dev/i2c-<bus> to use, and address is the I2C address of the device.
///
/// After opening the device, defaults to ignoring all I/O errors; see [Self::on_error] and
/// [ErrorHandling] for how to change this behavior.
I guess it would just be
(I thought doing it this way would help the learning experience. instead of just giving all the answers
)
///Creates a new instance of the LcdConnection Struct by receiving the Struct as a parameter and setting data sheet data for the backlight to be on
okay, quiz time. What do we do with on_error?
Let me change the comments and I'll try to answer
Too long I should've done more comments
Ok let's see
Well since we got rid of the on error field and the error handling enum and you said we won't needed and it seems because it's of our hardware control I guess we get rid of the public function on_error
yep, we don't need it 
what about backlight?
Well I wouldn't want to turn off the backlight I don't need tho just for having the functionality I would maybe leave it, but it's not necessary
then lets leave it
(Not only I don't need to, it's turn on by default is useless)
Yeah you are right let's delet it
If I never needed I can find it again
Ever*
set_bit we need, but you could add a comment
Set bit writes a letter/char or what does it do?
(We later go over on how it does , for now I guess I just need what it does)
It looks like the i2c board on the back of the screen has 8 bits where each bit activates one of the wires
The lcd library knows how to set all the wires to control it, but we also need to do the extra wires
normally this LCD uses 4 wires for data and 2 for reset and enable
It probably has 8 bits because it's a nice number of them to work with
Data being the characters, ig, reset like a clear but what would be enable? Turn on and off?
Oh yeah just like some integrated circuits may have 6 or 8 legs but like two of them do nothing
yep
I am not sure exactly what they do, https://cdn-shop.adafruit.com/datasheets/TC2004A-01.pdf explains it all though if you want to look
If you that knows lot more of embedded than me doesn't know I guess I really doesn't need to know (?
So..
Let's see I could comment
This is the timing diagram for the communication
looks like enable is to enable data transfer
///Function that sets the bits of the I2C circuit which are used to control the LCD wires
Ok done
impl Hardware for Pcf8574 {
fn rs(&mut self, bit: bool) {
self.set_bit(0, bit);
}
fn enable(&mut self, bit: bool) {
self.set_bit(2, bit);
}
fn data(&mut self, bits: u8) {
assert!(bits & 0xF0 == 0, "4-bit mode is required");
self.data = (self.data & 0x0F) | (bits << 4);
}
fn apply(&mut self) {
if let Err(e) = self.dev.smbus_write_byte(self.data) {
match &mut self.on_err {
ErrorHandling::None => (),
ErrorHandling::Panic => panic!("smbus_write_byte failed: {}", e),
ErrorHandling::Custom(f) => f(e),
}
}
}
}
You need to change the struct name, and we need to change apply
Change meaning delete?
no, we still need it but we need to find how the arduino_hal::I2c one does it's write
And I should change the text to Spanish also
So we go back to the documentation?
Sometimes I wish I was English (?
I would be.. Blondier(?
Thing is I am blonde but I was way more and I hate that fact(?
There's just one other text to change but I don't understand it
yep, did you find anything that may be what we want yet?
panic!("smbus_write_byte failed: {}", e)
What's smbys_write_byte
A function?
Because I don't see it
is from that Linux I2c thing self.dev.smbus_write_byte(self.data)
Oh I see it..
Oh
So let's first change that function let's see
Btw we are near to finishing changing stuff
Last time we where here
yep it's on that page
hmm, the linux version just writes
so looks like we need
Read more? Because seems it's only the signature
fn apply(&mut self) {
self.dev.write(address, data);
}
Oh
so, first problem, where do we get address from 
The adress of what exactly?
(Btw are we kinda doing our own library for our specific case?)
on i2c you can have multiple devices. Each has it's own address that it will respond to
you can thing of it like that
Oh right!
I remember
Remember the code I sent you
Well that library had an LCD object
Which constructor if I remember correctly
Needed, columns, rows, and the adresa
A dress*
Adress*
When trying to see like
What needed to be there
It seemed like it cooould vary but
The number was basically always the same and it worked with my LCD so
The adress should be that one let me scroll up
0x27
Yes
I remember that was an adress
And that it worked on mine ofc and that it kinda was always that a friend of mine did the same
I heard it could be another if unlucky
But technically it's that
So lets use that
const ADDRESS: u8 = 0x27;
I can't believe it was actually useful I was also.. (?
At the very top?
usually I put them after any use ... statements
Done so
I replace adress with ADRESS ig
fn apply(&mut self) {
self.dev.write(ADDRESS, &[self.data]);
}
Why the change to data?
here write expects a slice of bytes, but we just have 1
I didn't understand honestly how using the constant adress changed that
It expected data to be a slice of bytes?
It didn't it was just another change we needed
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error>
here bytes is a slice of bytes (u8)
-
idk what you mean slice of bytes instead of x amount of bytes, slice I only think of it as either strings slices or part of an array
-
why we have only one?
Well or vector you know
Unless it was a buffer and it's as slice of a buffer or smth-
A slice &[T] is a continuous sequence of T somewhere in memory (https://doc.rust-lang.org/book/ch04-03-slices.html)
Here the write function lets you write a buffer of some size to the device at the address
So we could do something like self.dev.write(address, &[1, 2, 3, 4, 5])
However, to point 2, we only have 1 byte to write because that is what the LCD device expects
going back to this ^ Result<(), Self::Error>, we have to decide what to do with it
We sort of removed all the error handling code
Mmm
What do you want to do if an error happens?
Unwrap when calling?
so trigger a panic? sure that works
I mean I thought we didn't needed it because it can't happen it was because Linux made this harder
So if we know more than the compiler, unwrap
Only handle if it could happen
ah, it can error, but here it can error if the devices doesn't respond to us
Which we expect not to happen as you have control over the hardware configuration
But you could do something
If we something is wrong we'll do it, idk, you know more(?
What would you do? Write error handling or unwrap?
I think here unwrap is fine
If it errors we don't really have anything we can do to fix it
Other than debugging it anyway
One idea could be to write the error message to the console so you could see it, but that will take more setup to do
Now about the last impl block we got rid of the thread use but.. Don't we kinds need delay? Tho also, couldn't we just use the hal delay?
kinda*
yep we can just use the arduino_hal one
Well, we still need the impl for the lcd crate to work 
impl Delay for Pcf8574 {
fn delay_us(&mut self, delay_usec: u32) {
arduino_hal::delay_us(delay_usec);
}
}
Shouldn't we add more doc comments or it's fine?
whatever you feel like
now we try it 
The module lcd it's completed say.
So we would use this module with the lcd dependencie we imported say by side?
Or only this module
Which uses
The lcd dependencie inside
Dependency*
For now we will use lcd library in main.rs for testing. Later you can wrap it all up in another struct
So we use the module for us and the library imported?
Made for us*
yep
Inside main function or the loop?
Do we want to create an lcd every loop or just once?
So below mod lcd I type use lcd::*?
you can add use lcd::*;
yep
I decoment mod lcd now?
I guess only one would make sense
What's that?
//! is like /// but documents the thing containing the doc
Ok so now I remove the slashes from mod lcd in main?
yep
I recommend //! because it keeps the lcd module docs in lcd.rs
I have 2 errors in main one in the lcd module
wait do they say 
lets deal with the first one
so the issue is we have a dependency named lcd and a module named lcd
, it doesn't know which you mean
try doing use crate::lcd::*; instead
~Let's make the module name capital ~ ask the one who made the crate to change the name.
Ok
Ok it works it's just the unused import warning as always
we can be more specific by using crate::lcd for the module and ::lcd for the library
Now the other
error[E0599]: no method named `write` found for struct `avr_hal_generic::i2c::I2c` in the current scope
--> src\lcd.rs:54:18
|
54 | self.dev.write(ADDRESS, &[self.data]);
| ^^^^^ method not found in `avr_hal_generic::i2c::I2c<Atmega, arduino_hal::pac::TWI, avr_hal_generic::port::Pin<Input, PD1>, avr_hal_generic::port::Pin<Input, PD0>, MHz16>`
|
::: C:\Users\fuchi\.cargo\registry\src\github.com-1ecc6299db9ec823\embedded-hal-0.2.7\src\blocking\i2c.rs:165:8
|
165 | fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error>;
| ----- the method is available for `avr_hal_generic::i2c::I2c<Atmega, arduino_hal::pac::TWI, avr_hal_generic::port::Pin<Input, PD1>, avr_hal_generic::port::Pin<Input, PD0>, MHz16>` here
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
3 | use embedded_hal::blocking::i2c::Write;
|
For more information about this error, try `rustc --explain E0599`.
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
3 | use embedded_hal::blocking::i2c::Write;
|

yep
This rule can get annoying, but it helps a lot in more complex situations
So now we need to make one of these LcdConnection structs
I leave the dp and pin variables?
yep we will need them shortly
Ok sure
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut i2c = arduino_hal::I2c::new(
dp.TWI,
pins.a4.into_pull_up_input(),
pins.a5.into_pull_up_input(),
50000,
);
Already an error let me see cargo check
error[E0308]: arguments to this function are incorrect
--> src\main.rs:13:19
|
13 | let mut i2c = arduino_hal::I2c::new(
| ^^^^^^^^^^^^^^^^^^^^^
14 | dp.TWI,
15 | pins.a4.into_pull_up_input(),
| ---------------------------- expected struct `PD1`, found struct `PF4`
16 | pins.a5.into_pull_up_input(),
| ---------------------------- expected struct `PD0`, found struct `PF5`
|
= note: expected struct `avr_hal_generic::port::Pin<_, PD1>`
found struct `avr_hal_generic::port::Pin<_, PF4>`
= note: expected struct `avr_hal_generic::port::Pin<_, PD0>`
found struct `avr_hal_generic::port::Pin<_, PF5>`
note: associated function defined here
--> C:\Users\fuchi\.cargo\git\checkouts\avr-hal-f3855d5807fdfd57\1aacefb\avr-hal-generic\src\i2c.rs:216:12
|
216 | pub fn new(
| ^^^
the arduino_hal just prevented a mistake
are pins a4 and a5 the i2c pins?
Ah let me see
Where so I have them conected
Do*
Since I haven't disconnected anything
It's wire gore
I'll see the simulation
Then I can check
20 and 21
so switch a4 and a5 to d20 and d21
now lets try some demo code
let mut lcd = Display::new(lcd_conn);
// initialization
lcd.init(FunctionLine::Line2, FunctionDots::Dots5x8);
lcd.display(
DisplayMode::DisplayOn,
DisplayCursor::CursorOff,
DisplayBlink::BlinkOff);
lcd.entry_mode(EntryModeDirection::EntryRight, EntryModeShift::NoShift);
// print something
write!(&mut lcd, "Hello, my number today is {: >4}", 42).unwrap();
In loop ig, right?
lets just do this once
Oh ok then main
One error for each lone of copying that
All undeclared types it seems
But I'll run cargo check to show you
error[E0433]: failed to resolve: use of undeclared type `FunctionLine`
--> src\main.rs:23:14
|
23 | lcd.init(FunctionLine::Line2, FunctionDots::Dots5x8);
| ^^^^^^^^^^^^ use of undeclared type `FunctionLine`
error[E0433]: failed to resolve: use of undeclared type `FunctionDots`
--> src\main.rs:23:35
|
23 | lcd.init(FunctionLine::Line2, FunctionDots::Dots5x8);
| ^^^^^^^^^^^^ use of undeclared type `FunctionDots`
error[E0433]: failed to resolve: use of undeclared type `DisplayMode`
--> src\main.rs:25:9
|
25 | DisplayMode::DisplayOn,
| ^^^^^^^^^^^ use of undeclared type `DisplayMode`
error[E0433]: failed to resolve: use of undeclared type `DisplayCursor`
--> src\main.rs:26:9
|
26 | DisplayCursor::CursorOff,
| ^^^^^^^^^^^^^ use of undeclared type `DisplayCursor`
error[E0433]: failed to resolve: use of undeclared type `DisplayBlink`
--> src\main.rs:27:9
|
27 | DisplayBlink::BlinkOff);
| ^^^^^^^^^^^^ use of undeclared type `DisplayBlink`
error[E0433]: failed to resolve: use of undeclared type `EntryModeDirection`
--> src\main.rs:28:20
|
28 | lcd.entry_mode(EntryModeDirection::EntryRight, EntryModeShift::NoShift);
| ^^^^^^^^^^^^^^^^^^ use of undeclared type `EntryModeDirection`
error[E0433]: failed to resolve: use of undeclared type `EntryModeShift`
--> src\main.rs:28:52
|
28 | lcd.entry_mode(EntryModeDirection::EntryRight, EntryModeShift::NoShift);
| ^^^^^^^^^^^^^^ use of undeclared type `EntryModeShift`
error[E0433]: failed to resolve: use of undeclared type `Display`
--> src\main.rs:20:19
|
20 | let mut lcd = Display::new(lcd_conn);
| ^^^^^^^ not found in this scope
|
help: consider importing one of these items
|
4 | use core::fmt::Display;
|
4 | use lcd::Display;
|
error[E0425]: cannot find value `lcd_conn` in this scope
--> src\main.rs:20:32
|
20 | let mut lcd = Display::new(lcd_conn);
| ^^^^^^^^ not found in this scope
try adding a use ::lcd::*;
because these types come from the library
Wait
So that was from our module?
Because I still have mod lcd up there
I thought that was for the library
use crate::lcd::*; is your lcd.rs module
crate refers to main.rs
error[E0425]: cannot find value lcd_conn in this scope
--> src\main.rs:20:32
|
20 | let mut lcd = Display::new(lcd_conn);
| ^^^^^^^^ not found in this scope
Wait
There's one more
But I can't get it
what did you call the LcdConnection?
error[E0599]: no method named write_fmt found for mutable reference &mut lcd::Display<_> in the current scope
--> src\main.rs:32:5
|
32 | write!(&mut lcd, "Hello, my number today is {: >4}", 42).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: this error originates in the macro write (in Nightly builds, run with -Z macro-backtrace for more info)
help: the following trait is implemented but not in scope; perhaps add a use for it:
|
3 | use core::fmt::Write;
|
help: there is an associated function with a similar name
--> C:\Users\fuchi.rustup\toolchains\nightly-2022-06-13-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\macros\mod.rs:500:27
|
500| let result = $dst.write($crate::format_args!($($arg)*));
use core::fmt::Write;
let lcd_conn = LcdConnection::new(i2c);
That where?
finally this warnings i considered relevant
warning: variable does not need to be mutable
--> src\main.rs:15:9
|
15 | let mut i2c = arduino_hal::I2c::new(
| ----^^^
| |
| help: remove this mut
|
= note: #[warn(unused_mut)] on by default
warning: unused Result that must be used
--> src\lcd.rs:54:9
|
54 | self.dev.write(ADDRESS, &[self.data]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
= note: this Result may be an Err variant, which should be handled
warning: rust_lcd (bin "rust_lcd") generated 2 warnings
remove the mut (as we just give it to LcdConnection) and then a .unwrap() for the second
So this is an example to see if the lcd turns on and writes stuff so we can finally use it?
yep
No errors no warnings, I connect it and use cargo run?
yep
Tho I predict
It won't work because of the same reason the first code didn't
Because of the wire gore it may not know what to do and we probably would have to specify something
Or maybe the library will handle it let's see
I knew it
Error: no matching serial port found, use -P or set RAVEDUDE_PORT in your environment
Caused by: Serial port not found.
error: process didn't exit successfully: ravedude mega2560 -b 57600 target\avr-atmega2560\debug\rust_lcd.elf (exit code: 1)
PS C:\Users\fuchi\OneDrive\Documentos\Codigos_Rust\rust_lcd>
com 6 again?
probably
tho maybe the reason is not the wire gore huh
Your mega is not an official one right?
Ah it says made in China so..
ravedude looks for a specific chip id which the non official ones don't use because price
hmm, it skipped a line
FunctionLine::Line2 is suspicious
Do I change it to line 1?
try it and see what happens
It like
Underlined the lines which it's written in
But it's written in the same place
I'll try now 0
If it's error then only line
Line and line 0 doesn't exist
So I will try 3
there is only 1, 2 (you can check the docs)
display.position(0, 1);
before the write!
It's merely an underliner
I see it's similar to it's c++ counter but more complicated (?
error
oh, wait for you it's lcd.
error[E0425]: cannot find value display in this scope
--> src\main.rs:34:5
|
34 | display.position(0, 1);
| ^^^^^^^ not found in this scope
For more information about this error, try rustc --explain E0425.
error: could not compile rust_lcd due to previous error
oh ok
It starts counting in 0
So you set the starting text there