Problem with Arduino using arrays in Structure - arrays

With an Arduino Uno I'm having a problem that is probably simple to solve for somebody who knows what they're doing. I'm trying to get this code to print out "-30" but all I get is "0" no matter what value I put in "setpt[x]" in the serial.print line in loop().
Thanks in advance, Don
typedef struct
{
byte seg_num[12];
byte ramp_hrs[12];
int setpt[12];
byte ramp_mins[12];
}record_type;
record_type profile[8];
void setup()
{
Serial.begin(9600);
Serial.println("*** START ***");
}
void loop()
{
profile[0] = (record_type) {(1,2,3),(5,7,9),(-40,-30,-25),(2,4,6)};
Serial.println(profile[0].setpt[2]); // fails with setpt[from 0 to 3]
}

Comma operators are used in your expressions like (1,2,3).
(1,2,3) is equivalent to 3 here.
You should use {} instead of () to initialize each arrays.
profile[0] = (record_type) {{1,2,3},{5,7,9},{-40,-30,-25},{2,4,6}};
Then, correct the index to get -30 instead of -25.
Serial.println(profile[0].setpt[1]);

Related

Arduino Endless Loop of Array

I need help to create endless loop for items in array, I want loop restart automaticly ;
My code is below ;
const int myArray [] = {3,5,6,7,1,2};
void loop() {
for (int element : myArray) {
Serial.println(element);
}
}
Thanks in advance
Wrap it in an infinite loop
while (true) {
for (int element : myArray) {
Serial.println(element);
}
}
As pointed out by hcheung in their comments, your loop() function should already be called as part of an infinite loop. Since that does not seem to be the case, then it is highly likely you have an error somewhere in your code. Have a look at the link posted by hcheung, which is a very basic Arduino application, and make sure you have something similar on your end, at least as far as the endless for loop calling loop() goes.

ENUM and array declaration using enum to create an array of objects

I am writing a wrapper for neopixel library. I am adding a full source code of my program:
I have created my own custom function toggle_led_strip which is using a function from the neopixelbus led strip library.
#include "NeoPixelBus.h"
#include <Adafruit_I2CDevice.h>
#define PixelCount 8 // this example assumes 4 pixels, making it smaller will cause a failure
#define PixelPin 27 // make sure to set this to the correct pin, ignored for Esp8266
#define colorSaturation 250
RgbColor blue(0,0,255);
RgbColor black(0);
NeoPixelBus<NeoGrbFeature, NeoEsp32Rmt0800KbpsMethod> strip(PixelCount, PixelPin);
void toggle_led_strip(RgbColor colour){
strip.SetPixelColor(0, colour);
strip.Show();
delay(100);
strip.SetPixelColor(0, black);
strip.Show();
delay(100);
}
void setup() {
strip.Begin();
// put your setup code here, to run once:
}
void loop() {
toggle_led_strip(blue);
// put your main code here, to run repeatedly:
}
Normally, when I want to create a colour variable, I must create it in such way:
RgbColor blue(0,0,255);
RgbColor black(0);
However, I am learning about different ways of creating colour objects and someone has suggested me to use ENUM and array method as such:
enum COLORS
{
blue,black
};
RgbColor a_color[2] = {
[blue] = {0,0,255},
[black] ={0}
};
From what I understand, the code above will set the first variable of enum (blue) to the {0,0,255} and the second variable of enum (black) to {0} so the result should be exactly the same as if I have used
RgbColor blue(0,0,255);
RgbColor black(0);
is that correct understanding?
Then I try to pass the color to the function as following:
//void toggle_led_strip(RgbColor colour) This is function prototype
toggle_led_strip(blue)
But it does not work when using enum and array method and works perfectly with the first method
Those who are interested in the solution:
void toggle_led_strip(COLORS colour){
strip.SetPixelColor(0, a_color[colour]);
strip.Show();
delay(100);
strip.SetPixelColor(0, a_color[black]);
strip.Show();
delay(100);
}
It turned out to be quite simple once you understand that an ENUM is treated as an array index and nothing else. It works as expected now.

How to define the callback for an esp32 arduino ble scan result

The definition to start a BLE scan is:
bool start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue = false);
The second parameter seems to be the callback when a scan is complete, being somewhat new to this Im unsure how to define it.
fwiw Ive tried this:
void OnScanResults(BLEScanResults scanResults)
{ }
and used it like this:
scanResults = scan->start(60, OnScanResults, true);
but obvious to others, that didnt work.
Please help me decypher that signature
void (*scanCompleteCB)(BLEScanResults)
you need to add & to OnScanResults because:
void (*scanCompleteCB)(BLEScanResults)
is a pointer to a function which takes a BLEScanResults, returns nothing and is called scanCompleteCB
So your call should be:
scanResults = scan->start(60, &OnScanResults, true);
just as a pointer to a int points to the address of a int
int pointedTo;
int* ptr = &pointedTo;

serial.println(String) prints "#" instead of the string

i'm just trying to recieve a string using a serial and to send this string back. So when i send a string to an arduino over a serial the arduino should automaticly send this string back.
i created this code:
String test;
void setup(){
Serial.begin(9600);
Serial.setTimeout(2);
test = "null";
}
void loop(){
if(Serial.available()){
test = Serial.readString();
}
Serial.println(test);
}
I guess it is not that difficult to understand. However now the arduino will always print a "#" instead of the variable test. My connected serial device is a bluetooth modul. (hc-06)
What did i do wrong?
Thank you!
(i also ran this code in the arduino emulator 123D Circuits. There it worked just fine)
You need change your code. Move println into if statement.
Try increase timeout interval, 2ms is not enough, good value (at 9600) lies above 10ms. Theoretically timeout should be at least 3.5 characters long and for current speed this equals ~0,4 ms. But in practice higher values are used.
String test;
void setup(){
Serial.begin(9600);
Serial.setTimeout(10);// or more
test = "null";
}
void loop(){
if(Serial.available()){
test = Serial.readString();
Serial.println(test);// moved into if
}
}
Update: Another simple solution to return characters back looks like:
void loop(){
if(Serial.available()) Serial.write(Serial.read());
}
Update 2: Had similar issue with BLE module HM10 (clone, not official). It was sending about 15 dummy bytes prior to any array. And i didn't solve it. But if weired bytes always the same you can make a simple trick using String.remove():
if(Serial.available()){
test = Serial.readString();
test.remove(0,5);
// test.remove - add code to remove last character
Serial.println(test);
}
Also try another terminal.

efficient function call

I need your help in writing a efficient program.
I have approx 50 functions say call_1(), call_2() ... call_50(). I need to call them based on the index read from a data packet, i.e if the field in data is 25 in need to call call_25(), if 10 then call_10().
I have written this in if else condition like
if (index == 5)
call_5()
elseif (index == 6)
..so on ..
But I think this is not the efficient way of writing. Any other ideas of implementing this scenario?
Can function pointers help here?
Appreciate your help. thanks.
Yes, use a lookup table of function pointers:
typedef void(*fp)(void);
void call_01(void);
void call_02(void);
/* ... */
fp functions[] = { &call_01,
&call_02,
/* ... */
};
void call()
{
unsigned int n = get_index();
functions[n]();
}
If the arguments are same for all 50 functions, use an array of function pointers:
typedef void (*FieldHandler)(void);
const FieldHandler handlers[50] = { call_0, call_1, /* ... and so on ... */ };
Then you just index into the array and call:
handlers[index]();
You can use an array of function pointers there easily, if all your functions have the same signature.
typedef void (*func)(void);
...
func dispatch_table[] = {
func0,
func1,
func2,
...
func50,
};
And later use like this
int function_index = packet_get_func_index( packet );
...
dispatch_table[ function_index ]();
Yes, function pointers are the way to go here.
I would suggest creating a table of function pointers and since your input is an index, you just index into the table to call the right function.
I'd use a switch statement:
switch(index) {
case 1: return call01();
case 2: return call02();
case 3: return call03();
}
This is not a lot more code than using function pointers, and it's (imho) more concise.
Yeah, that is pretty inefficient. I think the best way to proceed is to write a dispatcher of this form in the range of 0 - 255:
void (*dispatcher[255]);
Of course, you would need to assign all the necessary functions instead of doing the if statements, but this would be a heck of a lot faster:
dispatcher['a'] = &call_1;
dispatcher['b'] = &call_2;
dispatcher['c'] = &call_3;
...
Then you can just do:
dispatcher(index) and it would know which function to execute.
Hope that helps.

Resources