Why my arduino serial to LCD gets stuck after 26 loop? - c

I get a float from raspberry pi (via struct module) and my sketch only shows the data on an LCD screen.
After 26 corrects loop, on the 27th, the Arduino crashes.
Can you tell me what's wrong with the 27th?
Changing delay from 20ms to 1s: NOK
Put the byte pointer out of the function: NOK
float f;
void getFloat(){
byte *fdata = (byte *) &f;
while(Serial.available() <= 4){}
Serial.readBytes(fdata,4);
}
void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 0);
lcd.print("Ready to receive");
getFloat();
AZ=f;
getFloat();
AL=f;
lcd.setCursor(0, 0);
lcd.print("Moving ");
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print("AZ");
lcd.print(String(AZ));
lcd.setCursor(7, 1);
lcd.print("; AL");
lcd.print(String(AL));
delay(1000);
Serial.println("ok");
}
At the 27th, the arduino no longer acknoledge the data and the LCD shows :
==ving
AZy ; AL0.00=
=== Resolution ===
Before, I have to send twice the floats via the next code to get the last if not, I get the previous data on my arduino but i think the limitation comes from there :
def sendFloatToArduino(self,data):
self.serial.write(struct.pack('<f', data))
self.serial.flush()
def pointer(self,AZ,AL):
#send the data
print("AZ : "+str(AZ)+" ; AL : "+str(AL))
self.sendFloatToArduino(AZ)
self.sendFloatToArduino(AL)
self.sendFloatToArduino(AZ)
self.sendFloatToArduino(AL)
#wait for ack
while (self.serialArduino.in_waiting==0):
pass
print(self.serialArduino.readline())
After deleting the double sending, everything is fine.

Thanks for your answers.
The problem is not about the parsing as you said but with the LCD display.
I've tried converting floats to array and geting only 16 characters:
char str[16];
AZ=getFloat();
AL=getFloat();
char buffer1[20];
char buffer2[20];
dtostrf(AZ,7,5,buffer1);
dtostrf(AL,7,5,buffer2);
for (int i=0;i<8;i++){
if (i>1){
str[i]=buffer1[i-2];
str[i+8]=buffer2[i-2];
}
}
Serial.println(str);
But I get this on serial output : AZ358.54AL48.544\x12.BBHE\xb3CGm=\r\n => fixed with \0
I think the problem is elswhere : I have to send twice the floats via the next code to get the last if not, I get the previous data on my arduino but i think the limitation comes from there :
def sendFloatToArduino(self,data):
self.serial.write(struct.pack('<f', data))
self.serial.flush()
def pointer(self,AZ,AL):
#send the data
print("AZ : "+str(AZ)+" ; AL : "+str(AL))
self.sendFloatToArduino(AZ)
self.sendFloatToArduino(AL)
self.sendFloatToArduino(AZ)
self.sendFloatToArduino(AL)
#wait for ack
while (self.serialArduino.in_waiting==0):
pass
print(self.serialArduino.readline())

I can't figure out the problem, but you can try the following code. It's stronger I think.
float getFloat()
{
float res;
while (Serial.available() < sizeof(res))
;
Serial.readBytes((char*)&res, sizeof(res));
return res;
}
void loop()
{
// ...
AZ = getFloat();
AL = getFloat();
// ...
}

Related

Serial.print attatch a variable unintended

I'm programming an Arduino UNO with a SIM7600CE LTE Shield. I want to track the position and get the Received Signal Strength Indication. I can communicate with the shield and it works great. Now I want to transform the answers to my wanted values. Here is my Code:
void readRSSI(void){
char RecMessage[200]="0";
char s_RSSI[2]="0";
char s_BER[2]="0";
int i_RSSI=0, i_BER=0;
int i =0;
char * pch;
bool answer=false;
//while(myserial.available() == 0);
myserial.write("AT+csq\r");
do{
if(myserial.available() > 0){
RecMessage[i]=myserial.read();
i++;
if (strstr(RecMessage, "OK") != NULL){
answer = true;
}
}
} while (!answer);
myserial.flush();
if(answer){
pch = strstr(RecMessage,",");
int posi = pch - RecMessage;
s_RSSI[0]=RecMessage[posi-2];
s_RSSI[1]=RecMessage[posi-1];
s_BER[0]=RecMessage[posi+1];
s_BER[1]=RecMessage[posi+2];
i_RSSI=atoi(s_RSSI);
i_BER=atoi(s_BER);
}
Serial.flush();
Serial.println("RSSI Info:");
// Serial.println(RecMessage);
Serial.print("Received Signal Strength Indication: ");
Serial.print(i_RSSI);
Serial.print(" and Channel Bit Error Rate: ");
Serial.println(i_BER);
Serial.flush();
return;
}
The RecMessage is something like this:
AT+csq
+CSQ: 31,99
OK
So the Code basicly looks where the ',' is and take the left and the right numbers of it. It kinda works well, but somehow my output is this:
12:03:51.068 -> RSSI Info:
12:03:51.114 -> Received Signal Strength Indication: 31 and Channel Bit Error Rate: 9931
But thats not what it should be ... somehow it put's the i_RSSI at the end of the i_BER. The best Part is, if I comment out the Serial.print(i_RSSI);, it works right, the Serial shows just 99. Can somebody explain what I am missing?.
I'm using the Arduino IDE 1.8.19.
Assuming UART communication with AT commands and similar; then string null terminators are never sent on the bus, but instead CR and/or LF are used as delimiters. So you need to append null terminators manually on things you pick up from the bus. And this must be done before you call C standard lib functions like strstr or strlen which assume that you pass them a null terminated string.

Can't extract an integer from a thermometer byte reading

Afternoon all,
Apologies if this question is in the wrong format or in the wrong place, if this is the case, please flag and I'll change it or take it elsewhere.
I am using a development board to send a temperature reading to an LCD panel and I am really struggling to comprehend as to why the temperature at the moment that the program is run isn't being printed onto my LCD. A lot of the code is from framework given to me and is correct as far as I can tell.
My question stems from these functions:
uch get_temp()
{
int i;
DQ_HIGH();
reset(); //reset,wait for 18b20 responsion
write_byte(0XCC); //ignore ROM matching
write_byte(0X44); //send temperature convert command
for(i=20;i>0;i--)
{
//display(); //call some display function,insure the time of convert temperature
}
reset(); //reset again,wait for 18b20 responsion
write_byte(0XCC); //ignore ROM matching
write_byte(0XBE); //send read temperature command
TLV=read_byte(); //read temperature low byte
THV=read_byte(); //read temperature high byte
DQ_HIGH(); //release general line
TZ=(TLV>>4)|(THV<<4)&0X3f; //temperature integer
TX=TLV<<4; //temperature decimal
if(TZ>100)
{
TZ/100;
} //not display hundred bit
ge=TZ%10; //integer Entries bit
shi=TZ/10; //integer ten bit
wd=0;
if (TX & 0x80)
wd=wd+5000;
if (TX & 0x40)
wd=wd+2500;
if (TX & 0x20)
wd=wd+1250;
if (TX & 0x10)
wd=wd+625; //hereinbefore four instructions are turn decimal into BCD code
shifen=wd/1000; //ten cent bit
baifen=(wd%1000)/100; //hundred cent bit
qianfen=(wd%100)/10; //thousand cent bit
wanfen=wd%10; //myriad cent bit
NOP();
return TZ;
}
I have modified this function so that it should return the temperature integer (unsigned char TZ)
This function is then called here:
void Init_lcd(void)
{
ADCON1 = 0x07; //required setting of analog to digital
uch Temp;
TRISD = 0x00;
TRISA1 = 0;
TRISA2 = 0;
TRISA3 = 0;
writeCommand(0x0f);
writeCommand(0x38); //set to two line mode
clearDisplay();
writeString("MAIN MENU");
Temp = get_temp();
writeString(Temp);
writeCommand(0xC0); //change cursor line
}
It isn't printing anything after "MAIN MENU", which obviously means I'm doing something wrong. I can provide further clarification/code on request.
I should probably mention that I am NOT only simply looking for an answer of "paste this in and it'll work". Any feedback in which I understand my mistake and how to fix it is greatly appreciated.
Thanks in advance!
EDIT:
A few people are asking about my writing functions so for further clarification I'll paste them here:
void writeChar(unsigned char ch)
{
lcd = ch;
RS = 1;
RW =0;
E = 1;
lcdDelay();
E=0;
}
void writeString(char *stringToLcd)
{
while(*stringToLcd > 0)
{
writeChar(*stringToLcd++);
}
}
Temp is an unsigned char
uch Temp;
//...
Temp = get_temp();
writeString(Temp);
So, using writeString() will produce undefined results.
You should use write() instead (depending on the library you're using).
But you probably want to convert the return value of get_temp() to an ASCII string first, and display that using writeString().
Update:
void writeString(char *stringToLcd)
This function needs a char*, so you can't provide a single uch.
You need to convert Temp to a string first, using itoa() for example.
I could suggest you to implement a new function
void writeUCH(uch value)
{
unsigned char test = (value >= 100) ? 100 : (value >= 10) ? 10 : 1;
while(test > 0)
{
writeChar((value/test)+'0');
value = value%test;
test /= 10;
}
}
this line:
TZ/100;
will result in no change to TZ
what you really want is this:
TZ = TZ%100;
the value returned from get_temp() is an integer, not a ascii string. I would expect the LCD needs ascii characters, not the binary value of the bytes of an int variable.

Arduino: string to multiple variables

I'm trying to send the data from two sensors through 433MHz radio communication. I have succeeded in sending and receiving the string(array of char) "number1,number2".
Now I'm trying to store both numbers in separate int variables (the values are over 256).
I've tried with almost everything (sscanf and atoi mainly), but it does not seem to work.
To A0 and A1 I have connected two potentiometers, whose values I want to store in valorX and valorY in the receiver arduino.
What do you suggest?
I cannot assure I used correctly sscanf and atoi.
Transmitter code:
#include <VirtualWire.h>
int xvalue;
int yvalue;
void setup() {
Serial.begin(9600);
vw_set_ptt_inverted(true); //
vw_set_tx_pin(12);
vw_setup(4000);// speed of data transfer Kbps
}
void loop() {
xvalue=analogRead(A0);
yvalue=analogRead(A1);
int envioX = map(xvalue, 0, 1023, 001, 1000); //I prefer to not send 0
int envioY = map(yvalue, 0, 1023, 001, 1000);
//Mando los datos del joystic
char envioXY[]="";
sprintf(envioXY,"%d,%d",envioX,envioY);
EnviarDatos(envioXY);
delay(1000);
}
void EnviarDatos(char datos[]){
vw_send((uint8_t *)datos, strlen(datos)); //vw_send(message, length)
vw_wait_tx(); // Wait until the whole message is gone
}
Receiver code:
#include <VirtualWire.h>
char recibo[8]="";
int valorX;
int valorY;
void setup(){
vw_set_ptt_inverted(true); // Required for DR3100
vw_set_rx_pin(12);
vw_setup(4000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
Serial.begin(9600);
Serial.println("setup");
}
void loop(){
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)){ //check to see if anything has been received
for(int i=0;i<buflen;i++){
recibo[i]=char(buf[i]);
Serial.print(recibo[i]);
}
recibo[buflen]=NULL;
//String str(recibo);
//What here to get both int??
}
}
What do you suggest?
I cannot assure I used correctly sscanf and atoi.
So the main question is how to convert "number1,number2" to int1=number1 and int2=number2.
Thanks and cheers
Gabriel
Transmitter code:
You must declare storage for the sprintf to use. You have only declared a 1-byte array which contains a NUL (0 byte) as the first and only element [0]:
char envioXY[]="";
Change it to this, which declares a character array with 24 elements:
char envioXY[ 24 ];
Although uninitialized, sprintf will set the array elements as it formats your 2 integers.
Receiver code:
After recibo[buflen] = NULL;, you can parse it with this:
sscanf( recibo, "%d,%d", &valorX, &valorY );
The format string matches the sprintf format, and the address of the two integers is passed in, not just the two integers.

Sending decimals using radio.write(); with Arduino

I'm adapting a sketch I found to send sensor data over a wifi chip (Nrf2401), and although I get the message through, the value I send contains decimals (e.g. 24.59), but the received message will only be 24.
I'm sure there's something wrong on the transmitter part of the code, but I can't see what.
Here's my code:
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
// ce,csn pins
RF24 radio(8,7);
unsigned char data[3] = {
0};
unsigned long count=0;
void setup(void)
{
sensors.begin();
Serial.begin(57600);
Serial.println("**************V1 Send Sensor Data***********");
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.setChannel(0x4c);
// open pipe for writing
radio.openWritingPipe(0xF0F0F0F0E1LL);
radio.enableDynamicPayloads();
radio.setAutoAck(true);
radio.powerUp();
Serial.println("...Sending");
}
void loop(void)
{
sensors.requestTemperatures();
float currentTemp;
currentTemp = sensors.getTempCByIndex(0);
//assign 'T' to represent a Temperature reading
data[0] = 'T';
data[1] = currentTemp;
count++;
// print and increment the counter
radio.write(data, sizeof(float)+1);
Serial.print("Temperature sent: ");
Serial.println(currentTemp);
// pause a second
delay(500);
}
In this example, when I print currentTemp, it will display the decimals, but if I print data[1], it won't.
What am I missing?
You are assigning data [1] = currentTemp. Current temp is a float, not a character so this won't work. Decimals are lost because the float will be cast to a char in the assignment. Make data into a larger buffer and use sprintf to print currentTemp if you want to use it as a string. Really you should be writing just currentTemp to the radio and formatting on the other end, which will make the operation faster and require less bandwith to transmit (not to mention that transmitting and formatting are different concerns and should be separated, not coupled, when possible).

Arduino output pin outputs random activity

I am working on an Arduino project controlling a DIY RC truck that reads the output pins of an RC reciever and is supposed to PWMs a couple of pins accordingly. The pins are hooked onto a motor controller that takes PWM.
That is where the problem comes in. My reverse is working perfectly, but on the pin that does forward, I only get random activity. I'm using the Arduino Mega 2560.
Here is the code. The problem has been posted below it:
#include <Servo.h>
//Create variables for three channels
int RXCH[3];
volatile int RXSG[3];
int RXOK[3];
int PWMSG[3];
byte vooruit;
byte achteruit;
Servo stuur;
int mv = 13;
int ma = 10;
void setup() {
Serial.begin(115200);
stuur.attach(8);
//Assign PPM input pins. The receiver output pins are conected as below to non-PWM Digital connectors:
RXCH[0] = 6; //Throttle
RXCH[1] = 7; //Steering
//RXCH[2] = 5; //Nothing yet
//RXCH[3] = 2; //Nothing yet
//RXCH[4] = 7; //Nothing yet
//RXCH[5] = 8; //Nothing yet
for (int i = 0; i < 3; i++){
pinMode(RXCH[i], INPUT);
}
//TCCR1B = TCCR1B & 0b11111000 | 0x01;
//TCCR2B = TCCR2B & 0b11111000 | 0x01;
}
void loop() {
// Read RX values
for (int i = 0; i < 3; i++){ //For each of the 6 channels:
RXSG[i] = pulseIn(RXCH[i], HIGH, 20000); //Read the receiver signal
if (RXSG[i] == 0) { //Error catching
RXSG[i] = RXOK[i];
} else {
RXOK[i] = RXSG[i];
}
//Substitute the high values to a value between -255 and 255
PWMSG[0] = map(RXSG[0], 1000, 2000, -255, 255);
//Servo values, calibrated according to my steering servo.
PWMSG[1] = map(RXSG[1], 1000, 2000, 24, 169);
//Make sure that the value stays within the desired boundaries.
constrain (PWMSG[i], -255, 255);
//For debugginf purposes
Serial.print(" || Ch: ");
Serial.print(i);
Serial.print(" / PWMSG: ");
Serial.print(PWMSG[i]);
}
delay (5);
// Car goes forwards
if (PWMSG[0] > 40)
{
MV();
}
// Car goes backwards
if (PWMSG[0] < -40)
{
MA();
}
// Car stops
else
{
stopmotor();
}
stuur.write(PWMSG[1]);
Serial.println();
}
void MV()
{
vooruit = PWMSG[0];
analogWrite (mv, vooruit);
digitalWrite (ma, LOW);
Serial.print(" vooruit: ");
Serial.print(vooruit);
}
void MA()
{
achteruit = abs(PWMSG[0]);
analogWrite (ma, achteruit);
digitalWrite (mv, LOW);
Serial.print(" achteruit: ");
Serial.print(achteruit);
}
void stopmotor()
{
digitalWrite (ma, LOW);
digitalWrite (mv, LOW);
}
I don't really know if the code is considered pretty, or if I made some basic mistakes for that matter.
This is one of my first projects that I tried to do the right way, making comments and such, all well commented criticism is welcome.
What the code is supposed to do:
Move the stick on the transmitter forwards, the car goes forwards, and speed should be according to position of the stick.
Move the stick on the transmitter backwards, the car goes backwards, and speed should be according to position of the stick.
Move stick on the transmitter left or right, the servo in the car should react according to the value the Arduino calculated. You might wonder why I don't place the servo directly on the transmitter. Well, that's because I have many more future things in mind with this project, and now I can calibrate it way easier.
Problem:
When I move the stick on the transmitter forwards, and the Serial monitor is open, I get the right values on the Serial monitor, but the LED present on pin 13 just randomly blinks, very dim I must say.
I already tried to replace things like byte with int, but it had no effect. The rest of the code works fine.
Using some new code, I get a Serial response from every "stage", except the final stages that controls the pins.
#include <Servo.h>
//Create variables for channels
Servo wheel;
int MFORWARD_PIN = 13;
#define MBACKWARD_PIN 10
#define WHEEL_PIN 8
#define THROTTLE_PIN 6
#define STEERING_PIN 7
void setup() {
Serial.begin(115200);
wheel.attach(WHEEL_PIN);
pinMode(THROTTLE_PIN, INPUT);
pinMode(STEERING_PIN, INPUT);
pinMode(MFORWARD_PIN, OUTPUT);
pinMode(MBACKWARD_PIN, OUTPUT);
//TCCR1B = TCCR1B & 0b11111000 | 0x01;
//TCCR2B = TCCR2B & 0b11111000 | 0x01;
}
void loop() {
int throttle = read_throttle();
int steering = read_steering();
delay (5);
throttle_handle(throttle);
steering_handle(steering);
}
// Read RX values
int read_throttle(){
int throttle = pulseIn(THROTTLE_PIN, HIGH, 20000);
throttle = map(throttle, 1000, 2000, -255, 255); //Substitute the high values to a value between -255 and 255.
constrain (throttle, -255, 255); //Make sure that the value stays within the desired boundaries.
//Serial.println(throttle);
}
int read_steering() {
int steering = pulseIn(STEERING_PIN, HIGH, 20000);
steering = map(steering, 1000, 2000, 24, 169); //Servo values, calibrated according to my steering servo.
constrain (steering, 24, 169); //Make sure that the value stays within the disired boundaries.
//Serial.println("steering");
}
void move_forward(int val) {
analogWrite (MFORWARD_PIN, val);
digitalWrite (MBACKWARD_PIN, LOW);
Serial.print(" vooruit: ");
Serial.print(val);
}
void move_backward(int val)
{
val = abs(val);
analogWrite (MBACKWARD_PIN, val);
digitalWrite (MFORWARD_PIN, LOW);
Serial.print(" achteruit: ");
Serial.print(val);
}
void move_stop()
{
digitalWrite (MFORWARD_PIN, LOW);
digitalWrite (MBACKWARD_PIN, LOW);
}
void throttle_handle(int throttle) {
//Serial.print("throttle");
if (throttle > 40) {
move_forward(throttle);
}
if (throttle < -40) {
move_backward(throttle);
}
else {
move_stop();
}
}
void steering_handle(int steering) {
wheel.write(steering);
// Serial.println("steering:");
// Serial.print(steering);
}
Unused index:
Everywhere you loop over three values, whereas you only use two items in the array. So you'd better change all your sizes to 2 instead of 3, or you can define a NB_INPUT constant at the top of your source code, that you can change easily for more flexibility:
#define NB_INPUT 2
...
for (int i = 0; i<NB_INPUT; ++i) {
...
RXOK in setup():
your comment about arrays is justified, the first bug I can see in your code is that you read from the RXOK array, whereas you did not put any values in it. If you're sure that RXSG gets only zeroes from pulseIn() on the first pass of the Read RX values loop it can be ok, but I doubt it is. e.g.:
for (int i=0; i<3; ++i)
RXOK[i] = 0;
So you should put values in RXOK values in setup().
constant indexes in a for loop:
Then you map() the values from 1000->2000 to -255->255 for RXSG[0] and RXSG[1] inside the for loop, which will be done for the three iterations. I'm not sure what you want there, but if you want to do it for constant indexes, you'd better do it outside of the loop. But as you're checking a constraint on the -255->255 domain for each value of the iteration loop, I think you may want to do it on relative values:
PWMSG[i] = map(RXSG[i], 1000, 2000, -255, 255);
but it seems the domain is dependent on the index, so you may want to make a couple of defines at the top of your source code:
#define THROTTLE_IDX 0
#define STEERING_IDX 1
and put your map() in a if statement:
if (i == THROTTLE_IDX)
PWMSG[i] = map(RXSG[i], 1000, 2000, -255, 255);
elif (i == STEERING_IDX)
PWMSG[i] = map(RXSG[i], 1000, 2000, 24, 169);
# add a else statement if you need to do a map for the other values of the array
constrain(PWMSG[i], -255, 255)
general algorithm
I'm not sure you really need an array for your use case. You'd better keep a few variables around and have a better use of functions for your code to be readable and less bugprone:
#define THROTTLE_PIN 6
#define STEERING_PIN 7
#define WHEEL_PIN 8
#define MFORWARD_PIN 13
#define MBACKWARD_PIN 10
Servo wheel;
// sets up the arduino
void setup() {
Serial.begin(115200);
wheel.attach(WHEEL_PIN);
pinMode(THROTTLE_PIN, INPUT);
pinMode(STEERING_PIN, INPUT);
}
// input data handling
int read_throttle() {
int throttle = pulseIn(THROTTLE_PIN, HIGH, 20000);
return map(throttle, 1000, 2000, -255, 255);
}
int read_steering() {
int steering = pulseIn(STEERING_PIN, HIGH, 20000);
return map(throttle, 1000, 2000, 24, 169);
}
// output actions handling
void move_forward(int val) {
analogWrite(MFORWARD_PIN, val);
digitalWrite(MBACKWARD_PIN, LOW);
// Serial.print...
}
void move_backward(int val) {
analogWrite(MFORWARD_PIN, val);
digitalWrite(MBACKWARD_PIN, LOW);
// Serial.print...
}
void stop_motor() {
digitalWrite(MFORWARD_PIN, LOW);
digitalWrite(MBACKWARD_PIN, LOW);
}
void handle_throttle(int throttle) {
if (throttle > 40)
move_forward(throttle);
elif (throttle < -40)
move_backward(throttle);
else
stop_motor();
}
// general algorithm
void loop() {
int throttle = read_throttle();
delay(5);
handle_throttle(throttle);
}
There are more code duplication, but sometimes it is better to duplicate code than to make a code almost unreadable, and hard to debug while not offering any kind of flexibility/modularity. And here are a few other things I found in your code that should be corrected:
Naming convention: try to use good names for your functions (two letters variables, or dutch variables are not a good idea, I'm not english native and I always avoid to use my own language based names in code even for code I don't share, you never know who will read your code in 2 days, 2 months, or 2 years).
globals: Try to avoid using global variables as much as possible. Declare only constant in the global scope : const int foo = 1; or preprocessor defines #define foo 1, so that you do not spend too much of the little RAM space you have on your arduino. The only exception to that rule, which is very specific to arduino development, are objects (like Servo in your code) that you need to declare globally so you can set them up in the setup() function, and use them in the loop() function.
If I extrapolate on what you've written, you may want to add a handle_steering() function such as:
void handle_steering(int steering) {
if (steering > NN)
turn_left(steering);
elif (steering < NN)
turn_right(steering);
else
keep_straight();
}
and change the loop() to :
void loop() {
int throttle = read_throttle();
int steering = read_steering();
delay(5);
handle_throttle(throttle);
handle_steering(steering);
}
To make it a more general case of handling dynamically and flexibly a number of features, you could keep a few arrays:
PIN[]: containing the pins,
DOM_MIN[]: containing the minimum of the features' domain (for the map),
DOM_MAX[]: containing the maximum of the features' domain (for the map),
BOUND_MIN[]: containing the minimum boundaries (for the handle_steering condition),
BOUND_MAX[]: containing the maximum boundaries (for the handle_steering condition),
ACTION[]: containing the pointers to functions.
and then your algorithm would look like:
int read_input(int i) {
int value = pulseIn(PIN[i], HIGH, 20000);
return map(value, 1000, 2000, DOM_MIN[i], DOM_MAX[i]);
}
int handle_action(int i, int value) {
if (value > BOUND_MIN[i])
*(ACTION[i])(value);
elif (value < BOUND_MAX[i])
*(ACTION[i])(value);
else
*(ACTION[i])(-1);
}
void loop() {
for (int i=0; i<NB_INPUTS; ++i) {
int value = read_input(i);
delay(5);
handle_action(i, value);
}
}
but as you're still not comfortable with arrays (and I assume pointers as well), I would not recommend going further that way for the time being. First do it simple and make it work and then you could try to factorize it following the idea I'm exposing here. But you're making a software that is embedded, where the RAM is rare and the processing power is low, while your code space is cheap. So it's one of the few occasions where you'd better want to make a more redundant code that will stay in program space, whereas you want to manipulate as little symbols in the RAM. That's why I'm not showing you how the arrays are being declared/defined, and how to handle function pointers, because I don't think that solution (where you were heading) is the right way to do what you want.
Always remember, simpler is better!
HTH

Resources