I am trying to figure out what I am doing wrong. I have the problem down to a few lines of code. The program will freeze or behave incorrectly when code is used.
Just wondering if I am passing this correctly for the array's?
void callFunction(uint8_t &channel)
{
uint8_t address[8]; //1wire wire address and CRC
uint8_t scratchPad[8]; //holding for onewire capture
readScratchPad(address,scratchPad,channel);
}
void Temperature::readScratchPad(uint8_t rom[8],uint8_t data[8],const uint8_t &channel)
{
//read temperature data.
wireReset(); //reset();
selectChannel(channel); //necessary on -800
wireSelect(rom);
wireWriteByte(0xbe); // Read Scratchpad command
//display hex values of scratchpad
for ( int i = 0; i < 8; i++) { // we need 9 bytes
data[i] = wireReadByte();
}
}
The only other thing it could be is that I am passing a pointer to a function incorrectly like this:
function getNext()
{
uint8_t address[8];
getNextAddress(address);
}
bool Temperature::getNextAddress(uint8_t *vAddress)
{
if ( !wireSearch(vAddress))
{
wireResetSearch();
wireReset();
wireSkip();
return false;
}
return true;
}
I was passing the pointer as getNext(&address[8]), but it did not work either.
Thanks,
Related
I have problems with comparing strings.
I receive from mqtt a number of messages, I want to store the latest value for each topic (key)
I have shown the pertinent parts of my sketch.
#define MAX_SENSORS 6
// table of topic and value
char sensor_data[MAX_SENSORS][2][20];
initialize table
void init() {
....
for (int i=0;i<MAX_SENSORS;i++) // initialize table
{
strcpy(sensor_data[i][0],"?");
strcpy(sensor_data[i][1],"");
}
}
Message received here
void callback(char* topic, byte* b_payload, unsigned int length) {
// Convert byte* b_payload to string
for (int i = 0; i < length; i++) {
payload[i]=(char)b_payload[i];
};
payload[length]='\0';
for (int i = 0; i < MAX_SENSORS; i++)
{
Why does this (desparate debug) not work?
if (sensor_data[i][0]=="?") {
Serial.print("*");
}
Original
if (sensor_data[i][0]==topic) { // Slot matching topic found
strcpy(sensor_data[i][1],payload);
Serial.printf(" Slot %d",i);
break;
} else if (sensor_data[i][0]=="?") { // Empty slot found, store topic here
strcpy(sensor_data[i][0],topic);
strcpy(sensor_data[i][1],payload);
Serial.printf(" New %d",i);
break;
}
}
Serial.println();
}
It all probably originates because I'm confused between strings and char arrays?
edit
The assignment
strcpy(sensor_data[i][0],topic);
strcpy(sensor_data[i][1],payload);
seem to assign
concat(topic,payload) to sensor_data[i][0].
It all probably originates because I'm confused between strings and
char arrays?
Seems like it. C-strings (char* and char[]) are not comparable with ==, arduino's String class is. Either convert the left side of the comparison to String or use strcmp to compare the strings.
if (String(sensor_data[i][0])=="?") {
if (strcmp(sensor_data[i][0], "?") == 0) {
int arrays[2] = {0,1};
void setup () {
Serial.begin(9600);
pinMode(2,INPUT);
}
void loop () {
int buttonstate = digitalRead(2); //reads I/O pin 2
if (buttonstate==HIGH) { //if I/O pin 2 is HIGH do following
arrays[] = function(arrays); //calls function "function"
Serial.println(arrays[0]); //prints out arrays[0]
Serial.println(arrays[1]); //prints out arrays[1]
}
}
int function (int arrays [2]) {
int holder = arrays[1]; //switches place the values on the array
arrays[1] = arrays[0];
arrays[0] = holder;
return arrays[]; //return the modified array
}
What am I doing wrong here? Can someone explain why my code is wrong?
Why doesn't it just return the array and modify its content? I have read on other articles about pointers, but I couldn't understand how they worked.
Well, your worst misconception is thinking that C allows you to pass a complete array as parameter or return value.
First of all, you cannot do an assignment like
arrays[] = function(...);
This is incorrect, as there's no way to refer to the array as a whole. You can return a reference to an array, something like:
arrays = function(...);
always that your function returns a valid POINTER TO INTEGER, and always that you declare your arrays variable as int *arrays;, instead. But this has another problem... a pointer doesn't allocate memory for the pointed to values.
The best solution is to use the array reference to pass it to the function, and then make the function to operate on the array proper. Like in
function(arrays); /* you should have function exchanged the arrays values properly */
for (i = 0; i < 2; i++) /* print arrays contents and check values have been exchanged */
printf("arrays[%d] == %d\n", i, arrays[i]);
in this case, the arrays() function should have been implemented as
void function(int arrays[])
{
int temporary = arrays[0];
arrays[0] = arrays[1];
arrays[1] = temporary;
/* no return as function is declared void */
}
Of course, you can return the reference to the original array, and this can be helpful in some expressions, but think always that you are dealing with the same array anycase.
int *function(int *arrays) /* this parameter declaration is equivalent to the last one */
{
int temporary = arrays[0];
arrays[0] = arrays[1];
arrays[1] = temporary;
return arrays; /* reference to the first array element */
}
The array is passed to the function by reference.
If you modify the array in the function, the changes will persist after the function call.
int arrays[2] = {0, 1};
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
int buttonstate = digitalRead(2); //reads I/O pin 2
if (buttonstate == HIGH) { //if I/O pin 2 is HIGH do following
function(arrays); //calls function "function"
Serial.println(arrays[0]); //prints out arrays[0]
Serial.println(arrays[1]); //prints out arrays[1]
}
}
void function(int arrays[]) {
int holder = arrays[1]; //switches place the values on the array
arrays[1] = arrays[0];
arrays[0] = holder;
}
If you don't want to modify the existing array, you will need to pass another array.
int arrays[2] = {0, 1};
int arrays2[3];
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
int buttonstate = digitalRead(2); //reads I/O pin 2
if (buttonstate == HIGH) { //if I/O pin 2 is HIGH do following
function(arrays, arrays2); //calls function "function"
Serial.println(arrays2[0]); //prints out arrays2[0]
Serial.println(arrays2[1]); //prints out arrays2[1]
Serial.println(arrays2[2]); //prints out arrays2[2]
}
}
void function(int arrays[], int arrays_return[]) {
arrays_return[0] = arrays[1];
arrays_return[1] = arrays[0];
arrays_return[2] = arrays[0] + arrays[1];
}
You will need to make sure that the array have appropriate size, because there won't be any explicit error thrown if you write/read outside the array's range, but you may find some odd behavior that will be hard to debug.
I'm writing a class to save data to the EEPROM of an Arduino.
The class is called Memory.
The class contains different functions and variabeles.
char serverdefault[15] = "0032484716340";
int pricedefault = 30;
void Memory::FactoryReset()
{
TotalSold = 0;
TotalCash = 0;
Sold = 0;
Cash = 0;
Items = 0;
EEPROM_writeAnything(10, TotalSold);
EEPROM_writeAnything(20, TotalCash);
EEPROM_writeAnything(30, Sold);
EEPROM_writeAnything(40, Cash);
EEPROM_writeAnything(50, pricedefault);
EEPROM_writeAnything(60, Items);
EEPROM_writeAnything(70, serverdefault);
ReadAll();
}
Annother function allows to change the default server number.
void Memory::ChangeServer(char *number_str)
{
EEPROM_writeAnything(70, number_str);
ReadAll();
}
This function doesn't work.
I call the function in the void setup().
void setup()
{
Serial.begin(9600);
Serial.println("started");
Serial.println("factory reset");
mem.FactoryReset();
Serial.println("change server number");
mem.ChangeServer("1234567890123");
}
The value saved in the EEPROM is replaced by "b32484716340" instead of "1234567890123". What am i doing wrong?
In Memory::ChangeServer you are writing the pointer itself to EEPROM (i.e. the address), rather than the string that the pointer points to. One way to fix this would be:
void Memory::ChangeServer(char *number_str)
{
for (int i = 0; i <= strlen(number_str); ++i)
{
EEPROM_writeAnything(70 + i, number_str[i]);
}
ReadAll();
}
i'm working with I2C eeprom and Arduino. For now i tried to create simple keyboard that will start specific functions. I want to write to serial monitor potentiometer value, but i get trash instead it. How to fix it?
My functions:
int *readPot() ///read potentiometer value
{
int tempValue = analogRead(A0);
int *potValue = &tempValue;
return potValue;
}
void keyboardProcess() ///process keyboard input
{
int *potValue = readPot();
for(int i = 0; i < 2; i++)
{
btnReadings[i] = digitalRead(keysPins[i]);
}
if(btnReadings[0] == HIGH)
{
Serial.println("Potentiometer reading:" + *potValue);
}
}
One obvious problem is that you are returning the address to a local variable:
int *readPot() ///read potentiometer value
{
int tempValue = analogRead(A0);
int *potValue = &tempValue;
return potValue;
}
Here, the returned pointer points to the address of tempValue. This ceases to be valid once the function returns. Just use an int:
int readPot() ///read potentiometer value
{
return analogRead(A0);
}
Next, I doubt that this is a valid argument to Serial.println:
Serial.println("Potentiometer reading:" + *potValue);
but this should work:
int potValue = readPot();
Serial.print("Potentiometer reading: ");
Serial.println(potValue);
How can the method below be converted to C#?
private int GetTotalNumberLines()
{
// be safe about the array
int size = 0;
if (mLines == null) {
size = -1;
}
else {
size = Information.UBound(mLines);
}
return size;
}
In C# you can get the size of an array with Length:
size = mLines.Length;
There is no info in the question of what mLines is, but since the comment states // be safe about the array, I guess it's an array:
The only thin you need to change is the method UBound, which in C# is a property on the array called Length.
The entire code would look like this:
private int GetTotalNumberLines()
{
// be safe about the array
int size = 0;
if (mLines == null) {
size = -1;
}
else {
size = mLines.Length;
}
return size;
}