Attiny85 EEPROM erase, after power lost - arduino

my Attiny85 losts the whole EEPROM data, if I turn the power of.
I use the Arduino IDE and I'm sure, that The EEPROM was wrote, because I get Serial feedback. Here my code:
#include <EEPROM.h>
#include <SoftwareSerial.h>
SoftwareSerial SSerial(0, 1);
int addr = 0;
uint8_t val = 2;
void setup()
{
SSerial.begin(9600);
}
void loop()
{
EEPROM.write(addr, val);
delay(100);
uint8_t value = EEPROM.read(addr);
SSerial.print(addr);
SSerial.print("\t");
SSerial.print(value, DEC);
SSerial.println();
addr = addr + 1;
if (addr == 512)
while(1);
}
Thank you :)

Programming through ISP SPI erases eeprom (all values become 0xFF) by default but seems this feature can be setup in programmer settings. Programming through bootloader do not erase eeprom.
Thank you #Vladimir Tsykunov

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 to know how to send HEX values via SoftwareSerial on Arduino Uno

I’m trying to write Android Uno code to send HEX values via SoftwareSerial but when watching the Serial Monitor the output isn’t what I expected or wanted, and I am not experienced enough yet to know what to do next.
I don’t know where the FFFFs come from to be able to eliminate them.
My desired output is:
<br>
AA130120<br>
AA0400AE
What I get is:
<br>
FFFFFFFFAA1311E<br>
FFFFFFAA20
My code:
#include <SoftwareSerial.h>
// Define the RX and TX pins to establish UART communication with the MP3 Player Module.
#define Pin_RX 0 // to RX
#define Pin_TX 1 // to TX
#define d_sleep 10000
// Define the required MP3 Player Commands:
static byte ccPlay[] = {0xAA, 0x02, 0x00, 0xAC}; // Play:
static byte ccSetVol[] = {0xAA, 0x13, 0x01, 0x20}; // Set Volume (00-30):
// Define the Serial MP3 Player Module.
SoftwareSerial MP3(Pin_RX, Pin_TX);
void setup() {
// Initiate the serial monitor.
Serial.begin(9600);
}
void loop() { // Play a song.
ccSetVol[3] = {0x1E};
send_command_to_MP3_player(ccSetVol, 4);
delay(d_sleep);
send_command_to_MP3_player(ccPlay, 4);
delay(d_sleep);
}
void send_command_to_MP3_player(int8_t command[], int len){
//Serial.print("\nMP3 Command => ");
for (int i=0; i<len; i++) {
MP3.write(command[i]);
Serial.print(command[i], HEX);
}
delay(100);
}
Could you set the baud rate in the serial monitor to 9600Bd, run this code, and see if it spits out the bytes you expect in the serial monitor?
#define d_sleep 10000
static byte ccPlay[] = {0xAA, 0x02, 0x00, 0xAC};
static byte ccSetVol[] = {0xAA, 0x13, 0x01, 0x20};
void send_command_to_MP3_player(byte command[], int len) {
for (int i=0; i<len; i++) {
//Serial.println(command[i], HEX);
Serial.print(command[i], HEX);
}
//Serial.println();
delay(100);
}
void setup() {
Serial.begin(9600);
delay(1500);
}
void loop() {
ccSetVol[3] = 0x1E;
send_command_to_MP3_player(ccSetVol, 4);
delay(d_sleep);
send_command_to_MP3_player(ccPlay, 4);
delay(d_sleep);
}

Having problems blinking an LED on Arduino using information sent over CAN-bus

I've been messing around with CAN-bus to try and learn the basics so I can use it in a future project. I have 2 arduinos with MCP2515 chips connected that I am sending messages between.
I have been able to wire up the chips and send messages between the arduinos just fine, but when I went to modify the code to blink an LED if the first byte is 0x00 or 0x01 it wont blink. I added print statements to check that it is entering the loop, and it is, using the serial monitor I can see it yeet and yote, but digital pin 3 remains at ~0V.
This is probably more an arduino question than a CAN-bus question but could somebody help me understand why my LED wont blink? The code is entering the loop so it should be processing the command, and I initialized the pin to be an output, but i'm still not getting any blinking.
As a note, the transmitting arduino is sending alternating packets of data, first a packet with 0X01 as the first data byte, then with 0x00 as the first data byte. These data packets are separated by 5000 ms.
I am currently using the CAN library available here https://github.com/autowp/arduino-mcp2515
Code for receiving arduino
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg;
MCP2515 mcp2515(10);
int LED_PIN = 3;
void setup() {
Serial.begin(115200);
SPI.begin();
pinMode(LED_PIN, OUTPUT);
mcp2515.reset();
mcp2515.setBitrate(CAN_125KBPS);
mcp2515.setNormalMode();
Serial.println("------- CAN Read ----------");
Serial.println("ID DLC DATA");
}
void loop() {
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
Serial.print(canMsg.can_id, HEX); // print ID
Serial.print(" ");
Serial.print(canMsg.can_dlc, HEX); // print DLC
Serial.print(" ");
if(canMsg.data[0] == 0x00){
digitalWrite(LED_PIN,HIGH);
Serial.print("YEET");
}
if(canMsg.data[0] == 0x01){
digitalWrite(LED_PIN,LOW);
Serial.print("YOTE");
}
for (int i = 0; i<canMsg.can_dlc; i++) { // print the data
Serial.print(canMsg.data[i],HEX);
Serial.print(" ");
}
Serial.println();
}
}
and the code for transmitting arduino for completeness
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
void setup() {
canMsg1.can_id = 0x0F6;
canMsg1.can_dlc = 8;
canMsg1.data[0] = 0x01;
canMsg1.data[1] = 0x87;
canMsg1.data[2] = 0x32;
canMsg1.data[3] = 0xFA;
canMsg1.data[4] = 0x26;
canMsg1.data[5] = 0x8E;
canMsg1.data[6] = 0xBE;
canMsg1.data[7] = 0x86;
canMsg2.can_id = 0x036;
canMsg2.can_dlc = 8;
canMsg2.data[0] = 0x00;
canMsg2.data[1] = 0x00;
canMsg2.data[2] = 0x00;
canMsg2.data[3] = 0x08;
canMsg2.data[4] = 0x01;
canMsg2.data[5] = 0x00;
canMsg2.data[6] = 0x00;
canMsg2.data[7] = 0xA0;
while (!Serial);
Serial.begin(115200);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_125KBPS);
mcp2515.setNormalMode();
Serial.println("Example: Write to CAN");
}
void loop() {
mcp2515.sendMessage(&canMsg1);
delay(5000);
mcp2515.sendMessage(&canMsg2);
Serial.println("Messages sent");
delay(5000);
}
Sorry, i'm an idiot. I forgot that breadboard power lines are not connected all the way down the board. I connected the Arduino to the proper section of the breadboard to receive power and ground, but connected the LED to an unconnected ground pin.

Arduino SoftwareSerial Rx/Tx pin order error?

I'm writing code to run on an ATtiny being programmed by an Arduino as ISP. The ATtiny is to send AT commands over serial link to an RN42 Bluetooth module.
Since the ATtiny has no UART I'm using SoftwareSerial on pins 0 and 1. It seemed logical to put Tx on the "Data Out"/MISO pin and Rx on the "Data In"/MOSI pin. The documentation says to declare this like SoftwareSerial mySerial(Rx, Tx); but I found it only works if you declare it the other way round like SoftwareSerial mySerial(Tx, Rx);
I've taken a screenshot of my code and the pinout, I feel like I'm missing something but when I do it like this it works and makes the Bluetooth module enter command mode. Is the documentation the wrong way round?
Code and Pinout
I realised the error of my ways, I was unnecessarily setting the pinMode of the Rx and Tx pins. This threw me off as I thought setting the Rx pin to OUTPUT wouldn't work when actually it does, so I was outputting data on my Rx line and receiving it on the Tx line! The answer is to not assign direction and just let SoftwareSerial handle the pins. Pass the parameters in the order (Rx, Tx).
Here is my cleaner code that is working much better:
#include <SoftwareSerial.h>
const int Rx = 0; // pin 5 on ATtiny - DI/MOSI
const int Tx = 1; // pin 6 on ATtiny - DO/MISO
const int ButtonIn = 2;
const int OK_LED = 4;
int buttonState = 0;
SoftwareSerial serialBT(Rx, Tx);
void setup()
{
pinMode(ButtonIn, INPUT);
pinMode(OK_LED, OUTPUT);
serialBT.begin(9600);
}
void loop()
{
buttonState = digitalRead(ButtonIn);
if (buttonState == 0)
{
serialBT.print("$"); // $$$ enters RN42 command mode
serialBT.print("$");
serialBT.print("$");
delay(3000);
serialBT.println("R,1");
digitalWrite(OK_LED, HIGH);
delay(5000);
digitalWrite(OK_LED, LOW);
}
}

Arduino Nano Gnss Software Serial

I want to connect Arduino nano and GNSS (SIMCom’s SIM33ELA standalone GNSS module).
First I wrote a program for rx/tx, which is worked well, but now I want to use Software Serial and I got something wrong data.
#include <SoftwareSerial.h>
char incomingByte; // for incoming serial data
double tbs;
SoftwareSerial mySerial(8, 9); // RX, TX
void setup() {
Serial.begin(115200);
while (!Serial) {
}
mySerial.begin(115200);
while (!mySerial) {
}
}
void loop() {
if (mySerial.available()) {
tbs = mySerial.read();
incomingByte = (char)tbs;
Serial.print(incomingByte);
}
/*if (Serial.available() > 0) {
incomingByte = Serial.read();
Serial.print(incomingByte);
}*/
}
Any Idea?
Pictures about results:
Wrong data with Software serial
Good data with Serial
Mostly, don't read one character into a double floating-point variable. Just do this:
void loop()
{
if (mySerial.available()) {
char c = mySerial.read();
Serial.write( c );
}
}
You should also use AltSoftSerial on those two pins. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. It cannot transmit and receive at the same time. In fact, the Arduino can do nothing else while a character is transmitted or received.
For a GPS library, you could try NeoGPS. It's the only Arduino library that can parse the sentences from the newest devices. It's also smaller, faster, more reliable and more accurate than all other libraries.

Resources