I want to add serial control to my code, so i can set for example temperature from my PC for example with a command
temperature 250
would set variable named temperature to 250, i spent some time on the internet searching for some tips and example codes, but i couldn't find anything for my use case, i would need my code first to recognize to which variable to save value and then save the value to that variable.
Looks like it does pretty much what you need it to do.
So either learn how to use it, which admittedly is complex, or make it yourself, which is also complex but in a different way.
Sounds like a lot of work. As long as you stick to a clear protocol, it doesn't have to be very difficult. Start with this:
Does the command have to be 'temperature'? It might just as well be just 't'. Then a command like
t250
would set temperature to 250.
The only thing you then have to do is match the first character to 't' (which is ASCII 116) and parse the remainder of the input to an integer value using for instance atoi().
If you want to adhere to the command style you proposed, you could even parse the input into separate parts using strtok() and evaluate those separately, using the space (ASCII 32) as the separator.
Then once you've determined which command you're dealing with and what the parameter(s) is/are, you can perform the required function (e.g. set temperature to 250) using e.g. a swtich-case.
Serial.print(F("Enter command: "));
int i = parseGetline(); // read a line of text
do {
enum {
CMD_RED, CMD_GREEN, CMD_BLUE, CMD_RESET // make sure this matches the string
};
cmd = parseKeyword(PSTR("red green blue reset")); // look for a command.
if (cmd >= 0) {
n = parseNumber();
}
switch (cmd) {
case CMD_RED:
red = n;
break;
case CMD_BLUE:
blue = n;
break;
case CMD_GREEN:
green = n;
break;
case CMD_RESET:
red = green = blue = 0;
break;
case PARSER_EOL:
Serial.print("RED = "); Serial.print(red);
Serial.print(" GREEN = "); Serial.print(green);
Serial.print(" BLUE= "); Serial.println(blue);
break;
default:
Serial.println("Invalid command");
break;
}
} while (cmd >= 0);
}
It hasn't really been published, or converted to proper library format, because there isn't enough there. But adding "enough" makes it more complicated
How is about the following sketch which accepts the above Newline terminated alphanumeric string from the InputBox of Serial Monitor, extracts the alphabetic substring, converts the digital substring into numeric value, and then assigns the numeric value to the variable (temperature).
char myData[30] = {0};
char myString[20] = {0};
int i = 0;
int temperature;
void setup()
{
Serial.begin(9600);
}
void loop()
{
byte n = Serial.available();
if (n != 0)
{
byte m = Serial.readBytesUntil('\n', myData, 30);//receive all
myData[m] = '\0';
//Serial.println(myData); //show received string
//---------------------
for (i = 0; i < m; i++)
{
if (isAlpha(myData[i]))//checking if it is a letter
{
myString[i] = myData[i];
}
else
{
break; //exit for() loop is this is not a letter
}
}
myString[i] = '\0';
//Serial.println(myString);//show the alphabetic substring
//------------------------
if (strcmp(myString, "temperature") == 0)//check the substring
{
int y = strtoul(myData + i, NULL, 10);//convert to numeric value
//Serial.println(y); //show the numeric value
//--------------------------
temperature = y; //assgn the numeric value to variable
Serial.print("Temperature set at: ");
Serial.println(temperature);
}
}
}
Thanks for all of the help in replies, i decided to try the serial input basics example, but i have one more question i just added an if statement
if (messageFromPC == "setTemp")
{
setTemperature = integerFromPC;
}
But it doesn't work setTemperature doesn't change.
#include "Arduino.h"
const byte maxChars = 32;
char receivedChars[maxChars];
char tempChars[maxChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[maxChars] = {0};
int integerFromPC = 0;
int setTemperature = 0;
boolean newData = false;
//============
void setup()
{
Serial.begin(9600);
}
void loop()
{
SerialReceive();
}
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false)
{
rc = Serial.read();
if (recvInProgress == true)
{
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= maxChars)
{
ndx = maxChars - 1;
}
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker)
{
recvInProgress = true;
}
}
}
//============
void parseData()
{ // split the data into its parts
char *strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC = atoi(strtokIndx); // convert this part to an integer
if (messageFromPC == "setTemp")
{
setTemperature = integerFromPC;
}
}
//============
void showParsedData()
{
Serial.print("Message ");
Serial.println(messageFromPC);
Serial.print("Integer ");
Serial.println(integerFromPC);
Serial.println("setTemperature=");
Serial.println(setTemperature);
}
void SerialReceive()
{
recvWithStartEndMarkers();
if (newData == true)
{
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
Thanks, another question i defined multiple strings in an array so i have multiple aliases that work for setting the temperature, but i get an error saying cannot convert const char** to const char*, not sure how to make this work, also tried defining a string but also got errors, probably would need to convert to const char.
Serial_send_change_variables:80:43: error: cannot convert 'const char**' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'
int result = strcmp(alias, messageFromPC);
^
exit status 1
cannot convert 'const char**' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'