Read/Write EEPROM Arduino - arduino

I have a new ATmega328P CH340G Arduino Uno R3 board.
When I input a two-digit number (like 29), after power off and power on, the board shows only one digit (only 9). I want to show two digits.
enter image description here
Can you help me?
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
int addr = 5;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup() {
lcd.init();
Serial.begin(9600);
// initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0,0);
lcd.write(EEPROM.read(addr));
}
void loop() {
if (Serial.available()) {
while (Serial.available() > 0) {
char myValue = Serial.read();
EEPROM.write(addr,myValue);
lcd.write(myValue);
}
}
}

You are always writing to the same addr (i.e. 5) so you are most likely overwriting the previous character. Try incrementing your address after a write like this:
EEPROM.write(addr++, myValue);
(notice the ++ to increment the address)

Related

Receiving all zeros in payload sent from nodemcu to Arduino UNO over UART using SerialTransfer library

I have a nodemcu master streaming sensor values to Arduino Uno slave over UART using SerialTransfer.h. I have set up an additional serial port on Arduino digital pins 2, 3 for Rx, Tx using SoftwareSerial.h. I have wired the Tx on nodemcu to Rx on Uno and Rx on nodemcu to Tx on the Uno. I have a level-shifter to adjust for 3.3 V nodemcu and 5 V Arduino. I have made sure to provide a common ground.
I transmit a struct from nodemcu with sensor values (bool and int types, hard-coded for demo) but receive only zero values at the Arduino, as seen with Serial monitor. My code is below. I'd appreciate any inputs.
I have tried the following with no difference.
With and without an extra serial port on Uno created using SoftwareSerial.h
Reversing the set up with Arduino Uno master and nodemcu slave
With and without level-shifter on nodemcu Tx and Arduino Uno Rx
Here is the code for nodemcu master.
#include <Wire.h>
#include <SerialTransfer.h>
SerialTransfer masterMCU;
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
int fan;
int led;
} instructions = {
true,
201,
60
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(999);
masterMCU.begin(Serial);
delay(999);
}
void debug() {
Serial.print("MASTER: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print(instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
masterMCU.txObj(instructions, sizeof(instructions));
masterMCU.sendData(sizeof(instructions));
debug();
delay(999);
}
Here is the code for Arduino Uno slave.
#include <Wire.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>
SerialTransfer slaveMCU;
SoftwareSerial extra(2, 3); // Rx 2, Tx 3
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
int fan;
int led;
} instructions;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(201);
extra.begin(9600);
delay(201);
slaveMCU.begin(extra);
delay(201);
}
void debug() {
Serial.print("SLAVE: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print((bool)instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
if (slaveMCU.available()) {
slaveMCU.rxObj(instructions, sizeof(instructions));
debug();
} else if (slaveMCU.status < 0) {
Serial.print("ERROR: ");
if(slaveMCU.status == -1)
Serial.println(F("CRC_ERROR"));
else if(slaveMCU.status == -2)
Serial.println(F("PAYLOAD_ERROR"));
else if(slaveMCU.status == -3)
Serial.println(F("STOP_BYTE_ERROR"));
}
delay(999);
}
I made a few changes and data are received with correct values now.
I replaced delay() with millis() in master.
I replaced SerialTransfer::sendData() with SerialTransfer::sendDatum() in master. The former is for streaming multiple objects whereas the latter is for streaming a single object.
I replaced int types with uint8_t in the struct that is sent over wires in both master and slave.
The values are received correctly at Arduino Uno now. None of the changes made any difference until 3. above. I have retained the other changes as they also appear important to the result. Here is the final code that works for correct transmission and reception of objects from nodemcu master to Arduino Uno slave.
nodemcu master:
#include <Wire.h>
#include <SerialTransfer.h>
SerialTransfer masterMCU;
unsigned long tic = millis();
unsigned long toc = tic;
#define DELTA 1000
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
uint8_t fan;
uint8_t led;
} instructions = {
true,
201,
60
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(999);
masterMCU.begin(Serial);
delay(999);
}
void debug() {
Serial.print("MASTER: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print(instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
toc = millis();
if ((toc - tic) > DELTA) {
masterMCU.txObj(instructions, sizeof(instructions));
masterMCU.sendDatum(instructions), sizeof(instructions);
debug();
tic = toc;
}
}
Arduino Uno slave:
#include <Wire.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>
SerialTransfer slaveMCU;
SoftwareSerial Extra(2, 3); // Rx: 2, Tx: 3
unsigned long tic = millis();
unsigned long toc = tic;
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
uint8_t fan;
uint8_t led;
} instructions;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(201);
Extra.begin(9600);
delay(201);
slaveMCU.begin(Extra);
delay(201);
}
void debug() {
Serial.print("SLAVE: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print((bool)instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
if (slaveMCU.available()) {
slaveMCU.rxObj(instructions);
debug();
} else if (slaveMCU.status < 0) {
Serial.print("ERROR: ");
if(slaveMCU.status == -1)
Serial.println(F("CRC_ERROR"));
else if(slaveMCU.status == -2)
Serial.println(F("PAYLOAD_ERROR"));
else if(slaveMCU.status == -3)
Serial.println(F("STOP_BYTE_ERROR"));
}
}

Need some help in understanding some codes

I'm using RFID RC522 module in Arduino what the code does is, whenever the RFID tag is close to the reader it will read the tag no, with the current timestamp. But i need help in understanding the code line by line. I've understood a few lines which commented in the code but the rest i need help. Thank you
#include <RFID.h>
#include <SPI.h>
#define SS_PIN 10
#define RST_PIN 9
RFID rfid(SS_PIN, RST_PIN);
int serNum[4];
String cardno;
int interval = 15000; // millisec
long now = 0;
long lasttime = millis(); //millis() no.of millisec the sketch was runnning
String readerID = "100"; // This is the reader ID
void setup() {
Serial.begin(9600); //setting data rate in bits per second 9600
SPI.begin();
rfid.init();
}
void loop() {
now = millis();
if (rfid.isCard()) {
if (rfid.readCardSerial()) {
lasttime = now;
cardno = String(rfid.serNum[0]) +
String(rfid.serNum[1]) +
String(rfid.serNum[2]) +
String(rfid.serNum[3]) +
String(rfid.serNum[4]);
Serial.print(readerID);
Serial.print(":");
Serial.println(cardno); //printing the cardno in the serial monitor
}
}
rfid.halt();
delay(1000);
}
There are unused variables in your code. Let's get rid of them so that it is less confusing. I also added comments that explain the if statements.
#include <RFID.h>
#include <SPI.h>
#define SS_PIN 10
#define RST_PIN 9
RFID rfid(SS_PIN, RST_PIN);
String cardno;
String readerID = "100";
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.init();
}
void loop() {
if (rfid.isCard()) { // Look for a card. If found, return true.
if (rfid.readCardSerial()) { // Read the serial number of the card. if successful, return true.
cardno = String(rfid.serNum[0]) +
String(rfid.serNum[1]) +
String(rfid.serNum[2]) +
String(rfid.serNum[3]) +
String(rfid.serNum[4]);
Serial.print(readerID);
Serial.print(":");
Serial.println(cardno);
}
}
rfid.halt();
delay(1000);
}
Guessing from your comment, I think you want to understand how RFID class is implemented. I suggest looking at RFID.h and RFID.cpp.
RFID class has an array called serNum. My guess is that when you call readCardSerial(), an instance of RFID tries to store a card number in this array. If the operation is successful, it returns true.

Copying file bytes from SD Card to FRAM

I'm trying to copy a file from an SD card to an adafruit FRAM module. I'm wondering if I'm going about it the right way. I'm trying to read the file one byte at a time and then write that byte to a specific location on the Fram module.
I've been trying that approach using the sketch below and haven't been successful. I'm wondering if I'm approaching it the right way, and if so, where have I gone wrong with my sketch. Thanks.
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "Adafruit_FRAM_I2C.h"
Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();
uint16_t framAddr = 0;
void setup() {
Serial.begin(9600);
// setup SD-card
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println(" failed!");
while(true);
}
Serial.println(" done.");
}
void loop() {
uint16_t count = 0;
File myFile = SD.open("test.txt");
if (!myFile) {
// if the file didn't open, print an error and stop
Serial.println("error opening");
while (true);
}
const int S = 1;
byte buffer[S];
while (myFile.available()) {
// read from the file into buffer
myFile.read(buffer, sizeof(buffer));
Serial.print("0x"); Serial.print(count, HEX); Serial.print(": ");
Serial.println(buffer[count]);
//write fram (address,value)
fram.write8(count,buffer[count]);
}
myFile.close();
while (true) ;
}
I don't familiar with this FRAM, but you don't promote your address.
So the device write to the same address all the time and rewrite the memory.
Hope i help.
yoav

Send IR values using infrared emitter led on Arduino

i have Arduino Mega and an IR Emitting LED and i want to send data "Hex Data" that i choose using this LED and i have tried the IRRemote Library and i have successfully used the IRrecv class, but when using IRsend i didn't get any signal and have tried to look at the led through the mobile camera
the IR Emitter Pin is PWM 3 and have connected it to 3.3V once and to 5V once
#include <IRremote.h>
IRsend irsend;
void setup()
{
Serial.begin(9600);
}
void loop() {
if (Serial.read() != -1) {
for (int i = 0; i < 3; i++) {
irsend.sendSony(0xa90, 12); // Sony TV power code
delay(40);
}
}
}
and for the receiver:
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
}
any help is appreciated :) Hiso
i Have looked at the IRRemote.cpp library you refereed to and in the header file you can see that each Arduino board have a unique PWM pin that is used to transmit infrared data so use PWM 9 it's assured to work on Arduino Mega

Arduino Wire program seems to stop reading bytes after first i2c payload

I am trying to write a program that receives string data from i2c and displays it on an LCD. The first time data is received to the arduino, it renders it, however subsequent i2c payloads are ignored. My onReceive function has a status line display on the second line of the lcd which display the seconds() field from the timer chip. The seconds number does not seem to increment. However, the per-second dot flash as rendered in loop() does continue to blink, so the mcu is not frozen.
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Time.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
void setup()
{
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
}
void loop()
{
lcd.setCursor(15,1);
if (second() % 2 == 0)
lcd.write(".");
else
lcd.write(" ");
delay(100);
}
void receiveEvent(int howMany)
{
//char buf[howMany];
int i=0;
char output[16];
lcd.clear();
while(Wire.available())
{
char c = Wire.read(); // receive byte as a character
lcd.setCursor(i,0);
lcd.write(c);
i++;
//buf[i++]=c;
//buf[i+1]=0;
}
lcd.setCursor(0,1);
sprintf(output,"s%dNB%dI%d",second(),howMany,i);
lcd.write(output);
}
Your Arduino may be trapped in here:
while(Wire.available())
{
//...
Use:
if(Wire.available() > 0) {
//stuff
}
instead.

Resources