Why does the Radiohead library's method for receiving an array of characters use pass-by-reference for array length? - arduino

I am using the Radiohead library in an Arduino sketch for sending and receiving transmissions at 433.92 MHz. The sketch I am using works and I am able to send and receive sensor data (temperature, humidity) embedded in character strings "on air". However, I am puzzled by an implementation detail.
The recv() method of the RH_ASK class for receiving messages takes two arguments. The first is a pointer to an array of characters. This is understandable as messages are sent and received as character arrays. The second is the length of the array. This is an integer-valued number which is also passed as a pointer. Isn't it more convenient to send the integer-valued number itself i.e. pass-by-value instead of pass-by-reference?
Here is the relevant code snippet modeled on the article here.
Include the library, create an instance of the receiver object and initialize it.
// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Create Amplitude Shift Keying Object
RH_ASK rf_driver;
// Initialize ASK Object
rf_driver.init();
Receive a stream of characters into buffer, convert to string and parse for sensor readings.
// Set buffer to size of expected message
uint8_t buf[11];
uint8_t buflen = sizeof(buf);
// Check if received packet is correct size
if (rf_driver.recv(buf, &buflen)) // Why &buflen and not simply buflen?
{
// Message received with valid checksum
// Get values from string
// Convert received data into string
str_out = String((char*)buf);
// Thereafter, parse the string to extract sensor readings,
// and print them out.
}
I'd appreciate any help understanding the concept behind passing a perfectly good integer by reference instead of value.

Because the function needs to change the integer to the length of the received data.
https://github.com/PaulStoffregen/RadioHead/blob/e8581c127fac9bffb0ee800ae18847f673e9b4a5/RH_ASK.cpp#L462

Related

What endianess is used to store information in call to recvfrom()

Here is a simple code in socket API:
sock_raw = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
//...
data_size = recvfrom(sock_raw , buffer , bufsize , 0 , (struct sockaddr*)&saddr , (socklen_t*)&saddr_size);
//...
void print_ethernet_header(unsigned char* buffer)
{
struct ethhdr *eth = (struct ethhdr *)buffer;
fprintf(logfile , " |-Protocol : %x \n",ntohs(eth->h_proto));
}
In this question I was explained that h_proto member of struct ethhdr is stored in big-endian format.
Is it valid to say that the other members of this structure(h_source and h_dest are as well stored in big-endian format? And in such case is it valid to say that recvfrom() function stores data to buffer in big-endian format (I failed to find any info about this in man page to this function)? I think that this should be true because of rfc1042, but I am not sure.
recvfrom reads data from a socket and stores it in a buffer, but it doesn’t process the data: it stores it as it’s received. The order of values in the data depends on the network protocol. Most network protocols use big-endian (“network order”), so the data provided by recvfrom is typically big-endian — but that’s not a result of recvfrom.
In most cases you should use ntohs and ntohl to translate values as appropriate, and process arrays in the documented order. For h_source and h_dest, the documented order is indeed big-endian. If you’re writing kernel code, there are usually macros or helper functions available to do this for you; even printk has %pM format specifiers to handle MAC addresses.

Pin memory access type in exception handling

I am implementing an exception handling function using Pin. In my exception handling code, I particularly search for memory access error, say, memory read error and memory write error. I wrote some code below:
BOOL catchSignalTest(THREADID tid, INT32 sig, CONTEXT *ctx, BOOL hasHandler, const EXCEPTION_INFO *pExceptInfo, VOID *v)
{
ADDRINT exptAddr = PIN_GetExceptionAddress(pExceptInfo);
ADDRINT exptAddr = PIN_GetExceptionAddress(pExceptInfo);
FAULTY_ACCESS_TYPE ty = PIN_GetFaultyAccessType(pExceptInfo); <----- ty is unknown type!!!
}
.....
PIN_InterceptSignal(SIGSEGV, catchSignalTest, 0);
What really confuses me is that, even for a typical memory read access error below:
mov eax, [ebx] <--- ebx = 0x01, which makes the read operation failed
The FAULTY_ACCESS_TYPE of my code above is still UNKNOWN. Note that according to its definition, I suppose the access type should be FAULTY_ACCESS_READ.
Am I doning anything wrong here?
Before you call PIN_GetFaultyAccessType, you probably want to:
(1) call PIN_GetExceptionCode to get the EXCEPTION_CODE
(2) call PIN_GetExceptionClass to get the EXCEPTION_CLASS
as the fault access type may only be valid/useful if the class is EXCEPTCLASS_ACCESS_FAULT
At a guess, since you're accessing an odd location [with a 32 bit word fetch], the PIN library may set [probably sets] the x86's hardware "alignment check" (#AC) bit.
Then, you'll get EXCEPTCODE_ACCESS_MISALIGNED which would explain the results you get for the type (e.g. the alignment gets checked first, before the access). Since it's an alignment exception, the other access type codes don't really fit.
IMO, if the PIN library does not set #AC, then, EXCEPTCODE_ACCESS_MISALIGNED is kind of a pointless NOP.
You could try various ebx values like 4 against a known page that you changed the memory protections on (e.g. generate an access exception that you know is not also misaligned).

Permanently change a char variable

I am writing some code for a project where I have a GSM module interfaced with an Arduino to communicate certain notifications when a sensor is triggered and to receive commands via SMS. One such command is to set the 'call out' number via SMS. IE if I send the word 'Set' to the GSM module, the number the message is received from becomes the new number that the GSM module will call out to when sensors are triggered.
I have to initialise a default phone number in the code:
char ph_number[]="+35387914xxxx";
Then within my program I have some code to check for any SMS' that contain the 'Set' command and if so set ph_number = to the senders number.
I need to then permanently save that new number to become the default call out number, even if the Arduino is reset, until such time as a new Set command received. Is there a way to do this? Is it even possible?
You could store it in a special location in the FLASH or EEPROM, and read it from there on startup.
You can read / write to the EEPROM using the Arduino EEPROM library. This allows you to access one point in the memory at a time, an example sketch would be:
#include <EEPROM.h>
int a = 0;
int value;
void setup()
{
a = EEPROM.read(0); //reads from point 0 in the memory (the first point)
}
void loop()
{
value = analogRead(A0);
if(value != a){
a = value;
EEPROM.write(0, a);
}
}
When saving chars, they are first converted into their decimal equivalents before being saved, and must be converted out again afterwards. It's also important to remember that each point in the memory can store only 1 byte of data with a maximum value of 255, and the EEPROM has a limited number of read/writes - the factory specified maximum is 100000 but it can probably go higher.

How can you check for already stored variables on an Arduino Uno?

I have a program I want to make which will ask to see whether a variable already exists. If it does, it displays it, if it does not, it creates it and stores it in the Arduino using the PROGMEM command. Can someone explain more about PROGMEM and how to make the program I'm talking about?
Generally speaking if you are creating any variables in functions they are existing only there when function is closed all variables are deleted. If you want to keep them alive try to create global variables or use static before it;
like here
static int myvariable;
And here is answer for your question
if (myvariable!=NULL)
{
printfucntion(myvariable);
}
solution for eeprom
EEPROM Read
Reads the value of each byte of the EEPROM and prints it to the computer.
#include <EEPROM.h>
// start reading from the first byte (address 0) of the EEPROM
int address = 0;
byte value;
void setup()
{
Serial.begin(9600);
}
void loop()
{
// read a byte from the current address of the EEPROM
value = EEPROM.read(address);
Serial.print(address);
Serial.print("\t");
Serial.print(value, DEC);
Serial.println();
//move to next address of the EEPROM
address = address + 1;
// there are only 512 bytes of EEPROM, from 0 to 511, so if you are
// on address 512, wrap around to address 0
// if you have arduinoMega probably there is more eeprom space
if (address == 512)
address = 0;
delay(500);
}
I hope I helped.
This is a pretty stale question, and one that's not so popular. BUT is a valid question. In php, I am all the time using isset() to test for variables' existences. So, perhaps the OP is coming to embedded / C programming from the make-love-not-war world of php, where anything goes and isn't accustomed to the extremely literal and formal country of C.
As pointed out here, C language has #ifdef and #ifndef conditional defines that are often used for the exact purpose of testing if something is defined. To better understand the nuance of this usage, one should probably visit Programmers.SE and inquire about professional philosophy about conditional defines.
Me? I'm researching permanent variable storage on an Arduino via the EEPROM. Here are two different excellent articles. And about #ifdef's? I am just a lowly software engineer and save that for software architects. ;-) I have never intentionally implemented them, just see those a lot.
And a literal answer to the OP's question is: query the variable and try to use it. The Arduino's IDE compiler will scream if it is not defined.
Its simple , Just you need to Declare a variable.just compare with array of elements,you wanna compare with. If array element and enter element are present display using Serial.print() statement else you store it in array of buffer accumulating it. Display it.
As you are doing single link list

Global Variable Pointer to array in Sourceboost C

I declared these global variables:
volatile unsigned char BUFFER[7]={0,0,0,0,0,0,0};//to get all data
volatile unsigned char *PTR=&BUFFER[0];//points to start address
Inside the Microchip PIC interrupt function, the pointer reads the UART register and deference it to BUFFER[] array according to my code:
*PTR=rcreg;
PTR++;
I then check the data in function main():
for(i=0;i<3;i++){
if(BUFFER[i]==DATA[i]){
k++;
if(k==2){LED_On();}
}
}
and set ptr to point at the start address of BUFFER[]
ptr=BUFFER;
Question: Is this the best way and correct way to read data in the register? How can I use pointer in interrupt function?
Thank you for your kind attention and help in advance!
You may want to consider implementing a lock-free circular buffer to transfer data between the ISR and main():
Circular lock-free buffer
Non-blocking algorithm

Resources