Initializer fails to determine size of errror - c++

I'm new to a little new to programming, how do I store a variable in message? I'm trying to make a wireless temperature sensor using LoRa, with an Arduino Uno + Dragino shield. The results to be displayed on the things network. Everything else is working fine. Why do I get the error written below? {temp} does not work either.
CODE:
int temp = 25;
// Payload to send (uplink)
static uint8_t message[] = temp;
Error:
HelloWorld1:77: error: initializer fails to determine size of 'message'
static uint8_t message[] = temp;
^
HelloWorld1:77: error: array must be initialized with a brace-enclosed initializer
Multiple libraries were found for "lmic.h"
Used: C:\Users\\Documents\Arduino\libraries\arduino-lmic-master
Not used: C:\Program Files (x86)\Arduino\libraries\arduino-lmic-master
exit status 1
initializer fails to determine size of 'message'

The compiler has to know the size of the array when you declare it. It can find it out either directly from the value in [] (e.g. uint8_t message [2]) either, if there isn’t any value there, from the length of a braced-enclosed initializer, i.e. the list of comma-separated values inside a { } that you may assign to the array at declaration.
That aside, you can’t directly store an int value (2 bytes, signed) in an uint8_t (1 byte, unsigned). Since (I suppose) you need to transmit data as an uint8_t array you can do as follows:
int temp = 25;
// store temp in a uint8_t array with two elements (needed to store two bytes)
uint8_t message[2];
message[0] = temp >> 8; // Most significant byte, MSB
message[1] = temp; // Least significant byte, LSB
or
int temp = 25;
// store temp in a uint8_t array with two elements (needed to store two bytes)
uint8_t message[2] = {(temp >> 8), temp};
message[0] = temp >> 8; // Most significant byte, MSB
message[1] = temp; // Least significant byte, LSB
Theb transmit message, and on the receiver “reconvert” it to an int: temp = (message[0] << 8) | message[1];.

Related

Serialize array char, int8_t and int16_t in protobuf for C++

In protobuf, how would you serialize an array of char's, (u)int8_t or (u)int16_t? Should the message look like this:
message ArrayWithNotSupportedTypes
{
int32 type = 1;
string byte_stream = 2;
}
where type could store some unique id of the element type stored in the array.
And then the byte_stream is populated with contents of an array, where values are of one of the types above?
Also,I have seen that there is a type called bytes in protobuf, that is translated to an std::string in the corresponding grpc.pb.h files. Is there any advantage of choosing bytes ahead of string?
If the array size is not big, you can waste some space to make the interface simpler.
message ArrayWithNotSupportedTypes
{
repeated int32 data = 1; // one data entry per one element
}
If the array size is big, you can use your solution to indicate the type
message ArrayWithNotSupportedTypes
{
enum Type {
CHAR = 0;
INT8 = 1;
INT16 = 2;
}
optional Type type = 1;
optional bytes data = 2;
}
bytes and string are similar in C++: why protocol buffer bytes is string in c++?
Reference: https://developers.google.com/protocol-buffers/docs/proto3#scalar

Comparing an usart received uint8_t* data with a constant string

I'm working on an Arduino Due, trying to use DMA functions as I'm working on a project where speed is critical. I found the following function to receive through serial:
uint8_t DmaSerial::get(uint8_t* bytes, uint8_t length) {
// Disable receive PDC
uart->UART_PTCR = UART_PTCR_RXTDIS;
// Wait for PDC disable to take effect
while (uart->UART_PTSR & UART_PTSR_RXTEN);
// Modulus needed if RNCR is zero and RPR counts to end of buffer
rx_tail = (uart->UART_RPR - (uint32_t)rx_buffer) % DMA_SERIAL_RX_BUFFER_LENGTH;
// Make sure RPR follows (actually only needed if RRP is counted to the end of buffer and RNCR is zero)
uart->UART_RPR = (uint32_t)rx_buffer + rx_tail;
// Update fill counter
rx_count = DMA_SERIAL_RX_BUFFER_LENGTH - uart->UART_RCR - uart->UART_RNCR;
// No bytes in buffer to retrieve
if (rx_count == 0) { uart->UART_PTCR = UART_PTCR_RXTEN; return 0; }
uint8_t i = 0;
while (length--) {
bytes[i++] = rx_buffer[rx_head];
// If buffer is wrapped, increment RNCR, else just increment the RCR
if (rx_tail > rx_head) { uart->UART_RNCR++; } else { uart->UART_RCR++; }
// Increment head and account for wrap around
rx_head = (rx_head + 1) % DMA_SERIAL_RX_BUFFER_LENGTH;
// Decrement counter keeping track of amount data in buffer
rx_count--;
// Buffer is empty
if (rx_count == 0) { break; }
}
// Turn on receiver
uart->UART_PTCR = UART_PTCR_RXTEN;
return i;
}
So, as far as I understand, this function writes to the variable bytes, as a pointer, what is received as long as is no longer than length. So I'm calling it this way:
dma_serial1.get(data, 8);
without assigning its returning value to a variable. I'm thinking the received value is stored to the uint8_t* data but I might be wrong.
Finally, what I want to do is to check if the received data is a certain char to take decisions, like this:
if (data == "t"){
//do something//}
How could I make this work?
For comparing strings like intended by if (data == "t"), you'll need a string comparison function like, for example, strcmp. For this to work, you must ensure that the arguments are actually (0-terminated) C-strings:
uint8_t data[9];
uint8_t size = dma_serial1.get(data, 8);
data[size]='\0';
if (strcmp(data,"t")==0) {
...
}
In case that the default character type in your environment is signed char, to pass data directly to string functions, a cast is needed from unsigned to signed:
if (strcmp(reinterpret_cast<const char*>(data),"t")==0) {
...
}
So a complete MVCE could look as follows:
int get(uint8_t *data, int size) {
data[0] = 't';
return 1;
}
int main()
{
uint8_t data[9];
uint8_t size = get(data, 8);
data[size]='\0';
if (strcmp(reinterpret_cast<const char*>(data),"t")==0) {
cout << "found 't'" << endl;
}
}
Output:
found 't'

Convert array values of 1's and 0's to binary

In Arduino IDE, I am placing all of input values to an array like so:
int eOb1 = digitalRead(PrOb1);
int eLoop = digitalRead(PrLoop);
int eOb2 = digitalRead(PrOb2);
InputValues[0] = eOb1;
InputValues[1] = eLoop;
InputValues[2] = eOb2;
InputValues[3] = 0;
InputValues[4] = 0;
InputValues[5] = 0;
InputValues[6] = 0;
InputValues[7] = 0;
I would like to convert it to a byte array like so: 00000111.
Can you show me please. I tried using a for Loop to iterate through the values but it doesn't work.
char bin[8];
for(int i = 0; i < 8; ++i) {
bin &= InputValues[i];
}
If I understand your requirement correctly, you have an array of individual bits and you need to convert it into a byte that has the corresponding bits.
So to start, you should declare bin to be of type unsigned char instead of char[8]. char[8] means an array of 8 bytes, whereas you only need a single byte.
Then you need to initialize it to 0. (This is important since |= needs the variable to have some defined value).
unsigned char bin;
Now, unsigned char is guaranteed to have 1 byte but not 8 bits. So you should use something like uint8_t IF it is available.
Finally you can set the appropriate bits in bin as -
for(int i = 0; i < 8; ++i) {
bin |= (InputValues[i] << i);
}
There are two things I have changed.
I used |= instead of &=. This is the bitwise OR operator. You need to use OR because it only sets the correct bits in the LHS and leaves other bits untouched. An AND won't necessarily set that bit and will also mask away (set to 0), the other bits.
Shifted the bit in the array to the corresponding position using << i.

How can I know if the memory address I'm reading from is empty or not in C++?

So on an embedded system I'm reading and writing some integers in to the flash memory. I can read it with this function:
read(uint32_t *buffer, uint32_t num_words){
uint32_t startAddress = FLASH_SECTOR_7;
for(uint32_t i = 0; i < num_words; i++){
buffer[i] = *(uint32_t *)(startAddress + (i*4));
}
}
then
uint32_t buf[10];
read(buf,10);
How can I know if buff[5] is empty (has anything on it) or not?
Right now on the items that are empty I get something like this 165 '¥' or this 255 'ÿ'
Is there a way to find that out?
You need first to define "empty", since you are using uint32_t. A good ide is to use value 0xFFFFFFFF (4294967295 decimal) to be the empty value, but you need to be sure that this value isn't used to other things. Then you can test if if ( buf [ 5 ] == 0xFFFFFFFF ).
But if your using the whole range of uint32_t, then there is no way to detect if it's empty.
Another way is to use structures, and define a empty bit.
struct uint31_t
{
uint32_t empty : 0x01; // If set, then uint31_t.value is empty
uint32_t value : 0x1F;
};
Then you can check if the empty bit is set, but the negative part is that you lose a whole bit.
If your array is an array of pointers you can check to see by comparing it to {nullptr}, otherwise, you cannot unless you initialize all the initial indexes to the same value, and then check if the value is still the same.

How can I store hexadecimals inside an array? C++ MFC

I have to use an array of hexadecimals because I'm doing a program to communicate with a video server controller and he just understands messages in hexadecimal. I can connect the video controller with my server, but when I try to send messages using the send() function, passing an array of unsigned char that contains my information in hexadecimal, it doesn't work.
This is how I am using the array. I don't know if it is correct.
void sendMessage()
{
int retorno;
CString TextRetorno;
unsigned char HEX_bufferMessage[12]; // declaration
// store info
HEX_bufferMessage[0] = 0xF0;
HEX_bufferMessage[1] = 0x15;
HEX_bufferMessage[2] = 0x31;
HEX_bufferMessage[3] = 0x02;
HEX_bufferMessage[4] = 0x03;
HEX_bufferMessage[5] = 0x00;
HEX_bufferMessage[6] = 0x00;
HEX_bufferMessage[7] = 0xD1;
HEX_bufferMessage[8] = 0xD1;
HEX_bufferMessage[9] = 0x00;
HEX_bufferMessage[10] = 0x00;
HEX_bufferMessage[11] = 0xF7;
retorno = send(sckSloMo, (const char*) HEX_bufferMessage, sizeof(HEX_bufferMessage), 0);
TextRetorno.Format("%d", retorno);
AfxMessageBox(TextRetorno); // value = 12
if (retorno == SOCKET_ERROR)
{
AfxMessageBox("Error Send!! =[ ");
return;
}
return;
}
Pop quiz. What's the difference between:
int n = 0x0F;
and:
int n = 15;
If you said, "nothing," you're correct.
When assigning integral values, specifying 0x, 00 for octal, or nothing for decimal makes no difference in what is actually stored. This is a convenience for you, the programmer only. These are integral variables we're talking about -- they store numeric data only. They don't store or care about radix. In fact, you might be surprised to learn that when you assigned a numeric value to an integral variable, what is actually stored isn't decimal or hexadecimal or even octal -- it's binary.
Since you're storing these values as unsigned char, and char (unsigned or otherwise) is really just an integral type, then what you're doing is fine:
HEX_bufferMessage[0] = 0xF0;
HEX_bufferMessage[1] = 0x15;
HEX_bufferMessage[2] = 0x31;
but your question makes no sense:
Anyone knows if using an array of unsigned char is the right way to
store hexadecimals??