I'm attempting to send 8-bit byteArrays to an rfduino.
In the sketch, I got
void RFduinoBLE_onReceive(char *data, int len) {
int firstbyte = data[0];
Serial.println(firstbyte)
}
This works fine if the firstbyte is over 32. But if I'm sending a byteArray of [13, ...], firstbyte is parsed as 0.
I think I understand why (?):
RFduinoBLE parses incoming data as characters before sending it to this function, and bytes up to 32 are empty string.
So my question is: how can I use the RFduinoBLE-onReceive to read bytearrays with values below 32?
The following seems to work just fine:
void RFduinoBLE_onReceive(char *data, int length) {
uint8_t firstbyte = data[0];
}
or for arrays
uint8_t getData[20];
void RFduinoBLE_onReceive(char *data, int length) {
for (i = 0; i < length; i++) {
getData[i] = data[i];
}
}
Not quite sure what went right/wrong where, but I suspect either using int firstbyte instead of uint8_t firstbyte or casting uint8_t firstbyte = (uint8_t) data[0] did something I didn't expect.
Related
I have the following Arduino function:
void SendCommandToDisplay(byte message[], byte size)
{
byte header[] = {0x5A, 0xA5};
byte result[] = {};
memcpy(result, header, sizeof(header));
memcpy(result+sizeof(header), message, size);
for (byte i=0; i<sizeof(result); i++)
{
Serial.print(result[i], HEX);
Serial.print(' ');
}
}
Then I call this function as follows:
byte test[]={0x82, 0x20, 0x10, 0x00, 0x03};
SendCommandToDisplay(test, sizeof(test) / sizeof(byte));
And seems is not working, I'm doing something wrong or maybe I have to do a reference or pointer. Any clue?
You are not allocating memory for the result variable - in your case try this:
void SendCommandToDisplay(byte message[], byte size)
{
byte header[] = {0x5A, 0xA5};
byte result[sizeof(header)+size];
memcpy(result, header, sizeof(header));
memcpy(result+sizeof(header), message, size);
for (byte i=0; i<sizeof(result); i++)
{
Serial.print(result[i], HEX);
Serial.print(' ');
}
}
Once simple approach to inserting the byte count (of message) following header is to change how the header is initialized:
byte header[] = {0x5A, 0xA5, size};
Note: a prior edit added an alternative to use the sizeof(message) but that was incorrect and removed - sizeof(message) where message is a parameter returns the sizeof of a pointer which is 2 on an arduino.
I want to write some text into the flash memory of an Arduino ESP32. It works kinda but not as I want it to.
void writeString(const char* toStore, int startAddr) {
int i = 0;
for (; i < LENGTH(toStore); i++) {
EEPROM.write(startAddr + i, toStore[i]);
}
EEPROM.write(startAddr + i, '\0');
EEPROM.commit();
}
My call
writeString("TEST_STRING_TO_WRITE", 0);
only writes TEST into the memory. I do not understand why. Is that because of the _? Or am I missing something different?
Here is the used LENGTH macro
#define LENGTH(x) (sizeof(x)/sizeof(x[0]))
and the method I use to read the string from the memory again (which seems to work correctly):
String readStringFromFlash(int startAddr) {
char in[128];
char curIn;
int i = 0;
curIn = EEPROM.read(startAddr);
for (; i < 128; i++) {
curIn = EEPROM.read(startAddr + i);
in[i] = curIn;
}
return String(in);
}
Where on earth did you get that LENGTH macro from? It’s surreal.
sizeof will not do what you want here. It’s a compile-time function that computes the storage requirements of its argument. In this case it should return the length in bytes of a character pointer, not the string it points to.
You want to use strlen(), assuming your char* is a properly terminated C string. Add one to make sure the ‘\0’ at the end gets stored, too.
#define LENGTH(x) (strlen(x) + 1)
Below is the code to demonstrate the storing as well as retrieving of the string ssid in the EEPROM (permanent storage).
#include "EEPROM.h"
int addr = 0;
#define EEPROM_SIZE 64
// the sample text which we are storing in EEPROM
char ssid[64] = "CARNIVAL OF RUST";
void setup() {
Serial.begin(115200);
Serial.println("starting now...");
if (!EEPROM.begin(EEPROM_SIZE)) {
Serial.println("failed to init EEPROM");
while(1);
}
// writing byte-by-byte to EEPROM
for (int i = 0; i < EEPROM_SIZE; i++) {
EEPROM.write(addr, ssid[i]);
addr += 1;
}
EEPROM.commit();
// reading byte-by-byte from EEPROM
for (int i = 0; i < EEPROM_SIZE; i++) {
byte readValue = EEPROM.read(i);
if (readValue == 0) {
break;
}
char readValueChar = char(readValue);
Serial.print(readValueChar);
}
}
void loop() {
}
I am using the Arduino IDE to to write a sketch that passes data saved in progmem to a function, the function then writes the progmem data to local array.
The code is below:
const uint8_t Data_3 [256] PROGMEM = {0x11, 0x39.....}
void setup() {
Serial.begin(57600);
Data(Data_3, 0x00, 256);
}
void loop() {
}
void Data(const uint8_t *data, uint8_t bank, uint16_t bytes) {
uint8_t buff1 [256];
buff1[0] = data[0];
Serial.println(buff1[0],HEX); // <--Works fine prints the correct value
for ( uint16_t x = 0; x < bytes + 1; x++ ) {
buff1[x] = data[x];
Serial.println(buff1[x],HEX); // <--Just prints garbage
}
}
When I assign buff1[0] = data[0] and print the result the answer is correct. When I loop a print function with buff1[x] = data[x] I just get rubbish. Does anyone know the reason for this?
You have to use #include <avr/pgmspace.h> and Serial.print(pgm_read_byte(data+x)); otherwise it'll try to get data from the same address but from RAM, not from Flash memory.
Or copy into the buffer by memcpy_P(buff, data, bytes);
I'm using ArduinoJSON to write a couple of data points to my EEPROM on Arduino Uno. I'm running into a problem with getGroundedPR where I need to convert a uint8_t to a char to pass retrieved data into my JSON parser.
This is my first time using EEPROM so I'm willing to bet there's a better way to do this. Should I continue to use JSON or is there a better way? I'm being cautious of the 10k write limit (give or take) on the EEPROM.
the EEPROM read/write is commented out until I have my process nailed down
void IMUController::setGroundedPR(double p, double r) {
Serial.print("Setting IMU ground: ");
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["pitch"] = p;
root["roll"] = r;
root.printTo(Serial);
char buffer[256];
root.printTo(buffer, sizeof(buffer));
Serial.println();
// EEPROM.write(EEPROM_ADDRESS_IMU_GROUNDED, buffer);
}
double* IMUController::getGroundedPR() {
double ret[2] = {0, 0};
StaticJsonBuffer<200> jsonBuffer;
uint8_t json_saved = EEPROM.read(EEPROM_ADDRESS_IMU_GROUNDED);
char json[] = "asdf"; // convert json_saved to char here
JsonObject& root = jsonBuffer.parseObject(json);
if(!root.success()) {
// return the result
ret[0] = (double)root["pitch"];
ret[1] = (double)root["roll"];
return ret;
}
return ret;
}
The EEPROM functions read() and write() only deal with a single character. You need to use put() and get() to deal with arrays.
char buffer[256];
root.printTo(buffer, sizeof(buffer));
EEPROM.put(EEPROM_ADDRESS_IMU_GROUNDED, buffer);
And to read it back:
char json[256];
EEPROM.get(EEPROM_ADDRESS_IMU_GROUNDED, json);
JsonObject& root = jsonBuffer.parseObject(json);
You need to take care with he array sizes though, the EEPROM functions will get and put the number of bytes in the array (256). The string should be null terminated so the extra bytes shouldn't cause a problem.
I am currently trying to write a function to store data to the EEPROM on my Arduino. So far I am just writing a specified string and then reading it back when the program first runs. I am trying to store the length of the string as the first byte and my code is as follows;
#include <EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
char string[] = "Test";
void setup() {
lcd.begin( 16, 2 );
for (int i = 1; i <= EEPROM.read(0); i++){ // Here is my error
lcd.write(EEPROM.read(i));
}
delay(5000);
EEPROM_write(string);
}
void loop() {
}
void EEPROM_write(char data[])
{
lcd.clear();
int length = sizeof(data); // I think my problem originates here!
for (int i = 0; i <= length + 2; i++){
if (i == 0){
EEPROM.write(i, length); // Am I storing the length correctly?
lcd.write(length);
}
else{
byte character = data[i - 1];
EEPROM.write(i, character);
lcd.write(character);
}
}
}
The problem I am having is when I read the first byte of the EEPROM, I get the supposed length value. However, the loop only runs three times. I have commented some points of interest in my code, but where is the error?
You are indeed correct, on many counts, I think. Try this for writing:
// Function takes a void pointer to data, and how much to write (no other way to know)
// Could also take a starting address, and return the size of the reach chunk, to be more generic
void EEPROM_write(void * data, byte datasize) {
int addr = 0;
EEPROM.write(addr++, datasize);
for (int i=0; i<datasize; i++) {
EEPROM.write(addr++, data[i]);
}
}
You would call it like this:
char[] stringToWrite = "Test";
EEPROM_write(stringToWrite, strlen(stringToWrite));
To read then:
int addr = 0;
byte datasize = EEPROM.read(addr++);
char stringToRead[0x20]; // allocate enough space for the string here!
char * readLoc = stringToRead;
for (int i=0;i<datasize; i++) {
readLoc = EEPROM.read(addr++);
readLoc++;
}
Note that this is not using the String class developed for Arduino: reading and writing that would be different. But the above should work for char array strings.
Note however, that while EEPROM_write() looks generic now, it isn't really, since addr is harcoded. It can only write data to the beginning of EEPROM.