Error with char parameter methods Arduino Code - arduino

I keep getting the following error message when I'm trying to run my code. I can not figure out how to correct these errors so I can test everything. Even though these are just warning messages and the code says it uploads. I don't get any messages on my serial monitor printing any statements.
Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2); // set the LCD address for a 16 chars and 2 line display
const int guessPin = 7;
const int switch0Pin = 13;
const int switch1Pin = 12;
const int switch2Pin = 11;
const int switch3Pin = 10;
const int switch4Pin = 9;
int currentLetterIndex = 0;
int currentClueIndex = 0;
int currentGuess = 0;
int lastGuess = 0;
bool debug = false; // set to false to turn off serial output
unsigned long previousMillis = 0;
long restInterval = 20 * 1000; // 20 second time out to conserve battery
char clueBreak[] = "Get clue at the next house :)";
char hintBreak[] = "ah ah ah... must be patient";
char answerBreak[] = "santa";
char clue1[] = "The place we first meet?";
char hint1[] = "Company... not city";
char answer1[] = "pcc";
char clue2[] = "The play we saw in NY";
char hint2[] = "muppets... no...";
char answer2[] = "avenueq";
char clue3[] = "What we worn in Times Square";
char hint3[] = "look me in the eyes...";
char answer3[] = "diapers";
char clue4[] = "Where I said 'I Love You'";
char hint4[] = "And you later threw up on me...";
char answer4[] = "tonys";
char clue5[] = "";
char hint5[] = "+++ ++ ++++ ++++";
char answer5[] = "";
char clue6[] = "When do we do anything?";
char hint6[] = "'bye' 'see you +++++++'";
char answer6[] = "maybe tomorrow";
char clue7[] = "The animal you pet in gatlinburg";
char hint7[] = "spell the numbers...";
char answer7[] = "jellyfish";
char clue8[] = "These are only in California";
char hint8[] = "the one you used to sleep with";
char answer8[] = "seven eleven";
char clue9[] = "Where did you buy your cat?";
char hint9[] = "(-_-) R-O-B-O-T";
char answer9[] = "japan";
char clue10[] = "The ugliest car color...";
char hint10[] = "your second favorite color";
char answer10[] = "yellow";
char clue11[] = "Our first wine and paint";
char hint11[] = "__ _____ _____";
char answer11[] = "no drama llama";
const int cluesNum = 10; // clues + breaks
char * hints[] = {
hint1,
hint2,
hint3,
hint4,
hint5,
hint6,
hint7,
hint8,
hint9,
hint10,
hint11,
};
char * clues[] = {
clue1,
clue2,
clue3,
clue4,
clue5,
clue6,
clue7,
clue8,
clue9,
clue10,
clue11,
};
char * answers[] = {
answer1,
answer2,
answer3,
answer4,
answer5,
answer6,
answer7,
answer8,
answer9,
answer10,
answer11,
};
char currentLine1[17]; // need extra char for null pointer
char currentLine2[17]; // need extra char for null pointer
bool isDisplayingClue = true;
void setup()
{
pinMode(guessPin, INPUT);
pinMode(switch0Pin, INPUT);
pinMode(switch1Pin, INPUT);
pinMode(switch2Pin, INPUT);
pinMode(switch3Pin, INPUT);
pinMode(switch4Pin, INPUT);
lcd.init();
lcd.backlight();
if (debug)
{
Serial.begin(9600);
}
}
void updateDisplayFromArray(const char *str)
{
int limit = getCharSize(str)-1;
for (int i = 0; i >= 16; i++)
{
if (i <= limit)
{
currentLine1[i] = str[i];
}
if (i+16 <= limit)
{
currentLine2[i] = str[i+16];
}
}
}
int getCharSize(const char *cArray)
{
return sizeof(cArray) / sizeof(char);
}
void logger(const char *message)
{
if (debug)
{
Serial.println(message);
}
}
void restLCD()
{
lcd.setBacklight(0);
lcd.noDisplay();
}
void showLCD()
{
isDisplayingClue = false;
previousMillis = millis();
lcd.setBacklight(50);
lcd.display();
}
void TypeAnimation(const char *line1, const char *line2, int delayTime)
{
lcd.clear();
for (int i = 0; i <= getCharSize(line1)-1; i++) {
lcd.setCursor(i,0);
lcd.print(line1[i]);
delay(delayTime);
}
for (int i = 0; i <= getCharSize(line2)-1; i++) {
lcd.setCursor(i,1);
lcd.print(line2[i]);
delay(delayTime);
if (i == getCharSize(line2)-1) {
delay(1000);
}
}
}
void DelayAnimation(const char *line1, const char *line2, int delayTime)
{
setScreen(line1, line2);
delay(delayTime);
}
void setScreen(const char *line1, const char *line2)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(line1);
lcd.setCursor(0,1);
lcd.print(line2);
}
void TestAnimations()
{
showLCD();
PlayGuessingAnimation();
PlayCorrectAnimation();
PlayIncorrectAnimation();
ResetClues();
CurrentStatus();
ShowCurrentGuess();
DisplayClue(5000);
restLCD();
delay(5000);
currentLetterIndex++;
}
void ResetClues()
{
DelayAnimation("Resetting...", "",1500);
DelayAnimation("Merry Christmas!", "My Love :)",4000);
TypeAnimation("Old Man Turtle", "has been taken",250);
TypeAnimation("again...", ":(",250);
TypeAnimation("Solve the clues", "to find him",250);
TypeAnimation("Use the button 2", "submit da letter",250);
DelayAnimation("Now for your 1st", "clue",4000);
TypeAnimation("Goodluck my love", ":)",250);
NextClue();
currentLetterIndex = 0;
currentClueIndex = 0;
}
void ShowFinalAnimation()
{
TypeAnimation("You did it!", "",250);
TypeAnimation("You saved", "Old Man Turtle",250);
TypeAnimation("Old Man Turtle", "has left yo",250);
TypeAnimation("Use the button 2", "submit da letter",250);
DelayAnimation("Now for your 1st", "clue",4000);
TypeAnimation("Goodluck my love", ":)",250);
}
void loop()
{
logger("************* NEW LOOP *************");
//PlayGuessingGame();
TestAnimations();
}
void PlayGuessingGame()
{
bool buttonState = digitalRead(guessPin);
char *state = char(buttonState);
logger(state);
ConvertGuess();
if (buttonState)
{
logger("made it inside button guess clicked");
showLCD();
CheckGuess();
}
else
{
if (lastGuess != currentGuess)
{
logger("The guess has changed");
showLCD();
ShowCurrentGuess();
lastGuess = currentGuess;
}
else
{
logger("The guess hasn't changed :(");
if (!isDisplayingClue)
{
DisplayClue(1);
}
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > restInterval * .7)
{
DelayAnimation(" About to enter ", "-- Rest Mode --",1500);
}
if(currentMillis - previousMillis > restInterval)
{
logger("...REST MODE ACTIVATED...");
restLCD();
}
}
}
if (currentClueIndex > cluesNum)
{
ShowFinalAnimation();
}
}
void ConvertGuess()
{
bitWrite(currentGuess,0, !digitalRead(switch0Pin));
bitWrite(currentGuess,1, !digitalRead(switch1Pin));
bitWrite(currentGuess,2, !digitalRead(switch2Pin));
bitWrite(currentGuess,3, !digitalRead(switch3Pin));
bitWrite(currentGuess,4, !digitalRead(switch4Pin));
logger("Beginning conversion of guess");
logger("Pin 0:" + char(!digitalRead(switch0Pin)));
logger("Pin 1:" + char(!digitalRead(switch1Pin)));
logger("Pin 2:" + char(!digitalRead(switch2Pin)));
logger("Pin 3:" + char(!digitalRead(switch3Pin)));
logger("Pin 4:" + char(!digitalRead(switch4Pin)));
logger("new guess is " + char(ConvertIntToLetter(currentGuess)));
}
void CheckGuess()
{
PlayGuessingAnimation();
char guessLetter = ConvertIntToLetter(currentGuess);
char cLetter = clues[currentClueIndex][currentLetterIndex];
if (guessLetter == '-')
{
ResetClues();
}
else if (guessLetter == '+')
{
CurrentStatus();
}
else if (guessLetter == '?')
{
DisplayHint(5000);
}
else if (guessLetter == cLetter)
{
currentLetterIndex++;
if (currentLetterIndex > getCharSize(clues[currentClueIndex])-1)
{
PlayNextClueAnimation();
currentLetterIndex = 0;
currentClueIndex++;
}
PlayCorrectAnimation();
}
else
{
PlayIncorrectAnimation();
}
}
void ShowCurrentGuess()
{
char guess = char(ConvertIntToLetter(currentGuess));
if (guess == '-')
{
DelayAnimation(" DANGER!!! ", "THIS WILL RESET!",5000);
DelayAnimation("Press the button", "will reset",2000);
}
else if (guess == '+')
{
DelayAnimation("This will", "Show current status",2000);
}
else if (guess == '?')
{
DelayAnimation("This will", "Show you a hint",2000);
}
else if (guess == ' ')
{
DelayAnimation("You're Guessing ", "'_' (space)",1500);
}
else
{
DelayAnimation("You're Guessing ", char(guess),1500);
}
}
void CurrentStatus()
{
char currentAnswer[17] = "";
if (currentLetterIndex == 0)
{
strcpy(currentAnswer, "nothing yet :(");
}
else
{
strcpy(currentAnswer, GetCorrectGuesses());
}
DelayAnimation("You've Guessed ", strcat(char(currentClueIndex), " Clues"), 2000);
DelayAnimation("The Current", "Clues Is...", 2000);
DisplayClue(2000);
DelayAnimation("You've got right", currentAnswer, 3000);
}
char GetCorrectGuesses()
{
char result[17];
for(int i = 0; i >= currentLetterIndex; i++)
{
result[i] = answers[currentClueIndex][i];
}
return result;
}
void DisplayClue(int delayTime)
{
updateDisplayFromArray(clues[currentClueIndex]);
DelayAnimation(currentLine1,currentLine1,delayTime);
isDisplayingClue = true;
}
void DisplayHint(int delayTime)
{
updateDisplayFromArray(hints[currentClueIndex]);
TypeAnimation(currentLine1,currentLine1,delayTime);
}
void NextClue()
{
DelayAnimation(" Are you ready?? ", " Clue #" + char(currentClueIndex+1),3000);
DisplayClue(5000);
}
void PlayGuessingAnimation()
{
TypeAnimation("That is...", "",200);
}
void PlayNextClueAnimation()
{
TypeAnimation("HOORAY!!!", "",200);
DelayAnimation("You Got It Right", " Go You ;) ",2000);
TypeAnimation("On to the next", "",200);
NextClue();
}
void PlayCorrectAnimation()
{
DelayAnimation(" CORRECT!!!! ", "",1500);
}
void PlayIncorrectAnimation()
{
DelayAnimation(" Wrong :( ", " Try Again ",2000);
}
char ConvertIntToLetter(int number)
{
int result = '0';
switch (number)
{
case 0:
result = 'a';
break;
case 1:
result = 'b';
break;
case 2:
result = 'c';
break;
case 3:
result = 'd';
break;
case 4:
result = 'e';
break;
case 5:
result = 'f';
break;
case 6:
result = 'g';
break;
case 7:
result = 'h';
break;
case 8:
result = 'i';
break;
case 9:
result = 'j';
break;
case 10:
result = 'k';
break;
case 11:
result = 'l';
break;
case 12:
result = 'm';
break;
case 13:
result = 'n';
break;
case 14:
result = 'o';
break;
case 15:
result = 'p';
break;
case 16:
result = 'q';
break;
case 17:
result = 'r';
break;
case 18:
result = 's';
break;
case 19:
result = 't';
break;
case 20:
result = 'u';
break;
case 21:
result = 'v';
break;
case 22:
result = 'w';
break;
case 23:
result = 'x';
break;
case 24:
result = 'y';
break;
case 25:
result = 'z';
break;
case 26:
result = '!';
break;
case 27:
result = '%';
break;
case 28:
result = ' ';
break;
case 29:
result = '?';
break;
case 30:
result = '-';
break;
case 31:
result = '+';
}
return result;
}
Error Messages:
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino: In function 'void PlayGuessingGame()':
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:263:17: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
char *state = char(buttonState);
^~~~~~~~~~~~~~~~~
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino: In function 'void ShowCurrentGuess()':
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:378:40: warning: invalid conversion from 'char' to 'const char*' [-fpermissive]
DelayAnimation("You're Guessing ", char(guess),1500);
^~~~~~~~~~~
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:198:6: note: initializing argument 2 of 'void DelayAnimation(const char*, const char*, int)'
void DelayAnimation(const char *line1, const char *line2, int delayTime)
^~~~~~~~~~~~~~
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino: In function 'void CurrentStatus()':
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:391:44: warning: invalid conversion from 'char' to 'const char*' [-fpermissive]
strcpy(currentAnswer, GetCorrectGuesses());
~~~~~~~~~~~~~~~~~^~
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:25:0,
from sketch\ChristmasBoxV3.ino.cpp:1:
c:\program files (x86)\arduino\hardware\tools\avr\avr\include\string.h:305:14: note: initializing argument 2 of 'char* strcpy(char*, const char*)'
extern char *strcpy(char *, const char *);
^~~~~~
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:393:44: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
DelayAnimation("You've Guessed ", strcat(char(currentClueIndex), " Clues"), 2000);
^~~~~~~~~~~~~~~~~~~~~~
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:25:0,
from sketch\ChristmasBoxV3.ino.cpp:1:
c:\program files (x86)\arduino\hardware\tools\avr\avr\include\string.h:248:14: note: initializing argument 1 of 'char* strcat(char*, const char*)'
extern char *strcat(char *, const char *);
^~~~~~
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino: In function 'char GetCorrectGuesses()':
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:406:10: warning: invalid conversion from 'char*' to 'char' [-fpermissive]
return result;
^~~~~~
C:\Users\jb090\Documents\Arduino\ChristmasBoxV3\ChristmasBoxV3.ino:401:8: warning: address of local variable 'result' returned [-Wreturn-local-addr]
char result[17];
^~~~~~

char and char* is very different !
const char* can be slightly more tricky, but you first have to get the difference between a text and a character.
"Hello World" is a text, and usually treated as a pointer or [const] array.
'A' is a character, and internally stored the same way as the number 65 in a variable of type char.
More:
c# (or java) and c++ are very different, too. And there's a lot of truth in the saying "c++ is for masochists" :)
Your first problem
warning: invalid conversion from 'char' to 'char*'
char *state = char(buttonState);
comes from these lines:
bool buttonState = digitalRead(guessPin);
char *state = char(buttonState);
logger(state);
logger(const char*) needs a text to log, but you have a bool. Not sure how you wrote that in c#, and casting won't help. You eventually might want something like
bool buttonState = digitalRead(guessPin);
logger(buttonState? "guessPin is set": "guessPin is LOW");

You cannot cast a variable as a char by doing char(buttonState). In C you cast as follows: (char)buttonState.

There were some minor errors in my code (like incorrect for loop syntax) that was causing me to have run time errors.

Related

Stuck at solving leetcode Q5 using C [=34==ERROR: AddressSanitizer]

Please excuse for my massy code. This was best I could do.
I have been solving leetcode Q5 for a while; however, I couldn't solve it. This is the closest answer I have got.
I think it's acting correctly in terms of showing outputs. But has a runtime error when
let s = "tscvrnsnnwjzkynzxwcltutcvvhdivtmcvwdiwnbmdyfdvdiseyxyiiurpnhuuufarbwalzysetxbaziuuywugfzzmhoessycogxgujmgvnncwacziyybryxjagesgcmqdryfbofwxhikuauulaqyiztkpgmelnoudvlobdsgharsdkzzuxouezcycsafvpmrzanrixubvojyeuhbcpkuuhkxdvldhdtpkdhpiejshrqpgsoslbkfyraqbmrwiykggdlkgvbvrficmiignctsxeqslhzonlfekxexpvnblrfatvetwasewpglimeqemdgdgmemvdsrzpgacpnrbmomngjpiklqgbbalzxiikacwwzbzapqmatqmexxqhssggsyzpnvvpmzngtljlrhrjbnxgpcjuokgxcbzxqhmitcxlzfehwfiwcmwfliedljghrvrahlcoiescsbupitckjfkrfhhfvdlweeeverrwfkujjdwtcwbbbbwctwdjjukfwrreveeewldvfhhfrkfjkctipubscseioclharvrhgjldeilfwmcwifwhefzlxctimhqxzbcxgkoujcpgxnbjrhrljltgnzmpvvnpzysggsshqxxemqtamqpazbzwwcakiixzlabbgqlkipjgnmombrnpcagpzrsdvmemgdgdmeqemilgpwesawtevtafrlbnvpxexkeflnozhlsqexstcngiimcifrvbvgkldggkyiwrmbqaryfkblsosgpqrhsjeiphdkptdhdlvdxkhuukpcbhueyjovbuxirnazrmpvfascyczeuoxuzzkdsrahgsdbolvduonlemgpktziyqaluuaukihxwfobfyrdqmcgsegajxyrbyyizcawcnnvgmjugxgocysseohmzzfguwyuuizabxtesyzlawbrafuuuhnpruiiyxyesidvdfydmbnwidwvcmtvidhvvctutlcwxznykzjwnnsnrvcst"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int is_palindrome(char * s);
void get_substring(const char *str, char *substr, int start, int end);
char * longestPalindrome(char * s){
int strlength = strlen(s);
int end = strlength - 1;
int start = 0;
char substr[1000];
char *longstr = (char *)malloc(1000 * sizeof(char));
strcpy(longstr, "");
while (start <= end)
{
get_substring(s, substr, start, end);
// printf("%s\n", substr);
if (is_palindrome(substr) > strlen(longstr))
{
// printf("UPDATE : %s\n", substr);
strcpy(longstr, substr);
}
if (end == start)
{
start++;
end = strlength - 1;
}
else
{
end--;
}
}
// printf("LONG : %s", longstr);
return longstr;
}
void get_substring(const char *str, char *substr, int start, int end) {
int length = end - start + 1;
strncpy(substr, str + start, length);
substr[length] = '\0';
}
int is_palindrome(char * s){
int length = strlen(s);
int mid = length/2;
if (length % 2 == 0)
{
// printf("EVEN : %d\n", mid);
mid--;
int upperptr = mid+1;
int i = 0;
if (s[mid] != s[upperptr])
{
// printf("Returning FALSE [0]\n");
return 0;
}
while (mid-i >= 0 && upperptr+i <= length)
{
// printf("%c and %c and mid is %c\n", s[mid-i], s[upperptr+i], s[mid]);
if (s[mid-i] != s[upperptr+i])
{
// printf("Returning FALSE [1]\n");
return 0;
}
i++;
}
}
else
{
// printf("ODD: %d\n", mid+1);
int i = 0;
while (mid-i >= 0 && mid+i <= length)
{
// printf("%c and %c and mid is %c\n", s[mid-i], s[mid+i], s[mid]);
if (s[mid-i] != s[mid+i])
{
// printf("Returning FALSE [2]\n");
return 0;
}
i++;
}
}
// printf("Returning TRUE\n");
return length;
}
I had difficulties returning a local string. then found out that local string value can't be returned and has to be dynamically malloced and the pointer has to be returned.
So I fixed it (somehow, if it is right). But I reckon this is causing different - even harder - problems that I can't manage.

Arduino / DigiSpark / ATtiny85 - Receiving and parsing several pieces of data

i'm trying to make a digispark to work with bluetooth and NeoPixel, while i had success into making it go on and off i would like to expand on it.
I have used the Robin2 example 5 method to reciece, and parse my data in order to get the leds color the way i want.
https://forum.arduino.cc/index.php?topic=396450.msg2727728#msg2727728
this is the code in my case - the original is in the link above
void loop() {
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();
strip.setBrightness(xB);
controlLed();
newData = false;
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (bluetooth.available() > 0 && newData == false) {
rc = bluetooth.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 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
eFx = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // get the first part - the string
rC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
gC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
bC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
xS = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
xB = atoi(strtokIndx); // convert this part to an integer
}
void controlLed() {
colorWipe(strip.Color(rC1, gC1, bC1), xS);
colorWipe(strip.Color(20, 50, 100), 50);
}
now i have some issues, as the ATtiny85 memory is not that great i ran into issues when i try to send longer strings, basically i want to send all these:
int eFx = 1;
int rC1 = 100;
int gC1 = 100;
int bC1 = 100;
int xS = 20;
int xB = 100;
int rC2 = 5;
int gC2 = 50;
int bC2 = 200;
but when i try to parse it with the strtokIndx method above the digispark stops working (when i add more to what is already shown in the code ex above) i guess it's due to memory issues.
i understand part of the code,but not well enough to expand it in the direction that i want.
Right now the way it works is that when i send via BTooth info in this format asd<1,24,23,54,...,>qwe the recvWithStartEndMarkers () will grab all there is between < > and store it (?) in receivedChars
then i'm not sure why and how parseData() grabs this string and not something else, is it because of the function in the loop?
strcpy(tempChars, receivedChars);
parseData();
Well, i want to try to make this process go at it again, to recieve another string under [ ] and not < > and parseData2() (maybe) on receivedChars2 to get my last 3 INTs (color values for NeoPixel) parsed and stored in order to use them without having the digispark crash out of memory
The first step would be to change the
void recvWithStartEndMarkers() {
to detect also de diffrence between < and [ and run the proper code in order to store either in receivedChars or receivedChars2
not sure how to do that, also i'm not sure if this would be useful and would solve my memory issues.
any thoughts?
here is the full code i'm running
#include <Adafruit_NeoPixel.h> // NeoPixel Lib
#include <SoftSerial.h> // Serial Lib
#define LED_PIN 2
#define LED_COUNT 30
SoftSerial bluetooth(4, 5); // RX TX
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
const byte numChars = 42;
char receivedChars[numChars];
char tempChars[numChars];
boolean newData = false;
int eFx = 1;
int rC1 = 100;
int gC1 = 100;
int bC1 = 100;
int xS = 20;
int xB = 100;
int rC2 = 5;
int gC2 = 50;
int bC2 = 200;
void setup() {
bluetooth.begin (9600);
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
}
void loop() {
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();
strip.setBrightness(xB);
controlLed();
newData = false;
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (bluetooth.available() > 0 && newData == false) {
rc = bluetooth.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 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
eFx = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // get the first part - the string
rC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
gC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
bC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
xS = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
xB = atoi(strtokIndx); // convert this part to an integer
}
void controlLed() {
colorWipe(strip.Color(rC1, gC1, bC1), xS);
colorWipe(strip.Color(20, 50, 100), 50);
}
void controlLed2() {
colorWipe(strip.Color(rC2, gC2, bC2), xS);
}
void colorWipe(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}

why i m getting warning: comparison between pointer and integer

I'm getting warning msg saying:
comparison between pointer and integer
char * replaceWord(const char * str, const char * oldWord, const char * newWord)
{
char * resultString;
int i, count = 0;
int newWordLength = strlen(newWord);
int oldWordLength = strlen(oldWord);
//count the no of occurance of word in string in a file
for (i = 0; str[i] !='\0'; i++)
{
if (strstr(str[i], oldWord) == str[i])//i m getting warning here
{
count++;
i = i + oldWordLength - 1;
}
}
// Making a new string to fit in the replaced words
resultString = (char *)malloc(i + count * (newWordLength - oldWordLength) + 1);
i = 0;
while (*str!='\0')
{
// Compare the substring with result
if(strstr(str, oldWord) == str)//here i used same syantax its working but not above
{
strcpy(&resultString[i], newWord);
i += newWordLength;
str += oldWordLength;
}
else{
resultString[i] = *str;
i += 1;
str +=1;
}
}
resultString[i] = '\0';
return resultString;
}
From the man page for strstr():
#include <string.h>
char *strstr(const char *haystack, const char *needle);
So, strstr() returns the substring's char* pointer as the result, and you are comparing it against a char variable (str[i]), thus the error.

how to tokenize a string in arduino

i am using arduino due. what i am trying to do is to receive a string at serial. like this one:
COMSTEP 789 665 432 END
if the string starts with comstep, then to tokenize the string and get an integer array {789, 665, 432}.
is there anyway to do that?
P.S: im a noob at programming, so any help is appreciated.
I have a function that I wrote long ago to parse strings up in an easy manner. It is in use on several of my Arduino projects.
Sample usage:
char pinStr[3];
char valueStr[7];
int pinNumber, value;
getstrfld (parms_in, 0, 0, (char *)",", pinStr);
getstrfld (parms_in, 1, 0, (char *)",", valueStr);
pinNumber = atoi (pinStr);
value = atoi (valueStr);
The functions:
// My old stand-by to break delimited strings up.
char * getstrfld (char *strbuf, int fldno, int ofset, char *sep, char *retstr)
{
char *offset, *strptr;
int curfld;
offset = strptr = (char *)NULL;
curfld = 0;
strbuf += ofset;
while (*strbuf) {
strptr = !offset ? strbuf : offset;
offset = strpbrk ((!offset ? strbuf : offset), sep);
if (offset) {
offset++;
} else if (curfld != fldno) {
*retstr = 0;
break;
}
if (curfld == fldno) {
strncpy (retstr, strptr,
(int)(!offset ? strlen (strptr)+ 1 :
(int)(offset - strptr)));
if (offset)
retstr[offset - strptr - 1] = 0;
break;
}
curfld++;
}
return retstr;
}
// Included because strpbrk is not in the arduino gcc/g++ libraries
// Or I just could not find it :)
char * strpbrk (const char *s1, const char *s2)
{
const char *c = s2;
if (!*s1) {
return (char *) NULL;
}
while (*s1) {
for (c = s2; *c; c++) {
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
if (*c == '\0')
s1 = NULL;
return (char *) s1;
}
A light-weight approach (no strict checks on valid parses of the integers and ignoring any list elements past a fixed maximum):
char buf[32] = "COMSTEP 789 665 432 END"; // assume this has just been read
int res[8], nres = 0;
bool inlist = false;
for (char *p = strtok(buf, " "); p; p = strtok(0, " "))
if (inlist)
{
if (!strcmp(p, "END"))
{
inlist = false;
break;
}
else if (nres < sizeof(res) / sizeof(*res))
res[nres++] = atoi(p);
}
else if (!strcmp(p, "COMSTEP"))
inlist = true;
if (!inlist)
for (size_t i = 0; i < nres; ++i)
printf("%d%s", res[i], i + 1 < nres ? " " : "\n"); // do whatever

Arduino mega crashes while reading somewhat large .txt from SD

I have an Arduino mega with an SD Shield and a GSM shield. I'm trying to send one sms to 200 numbers from a text file on the SD card, but the Arduino reboots every time I try to send to over 100 numbers. It doesn't crash when I try to send to 70 numbers. I only read one number at a time so I don't understand the problem. I'm pretty new to Arduino programming.
Please help me this is for a tournament. Here's the code:
#include <avr/pgmspace.h>
#include <SPI.h>
#include <SD.h>
#include <GSM.h>
#define PINNUMBER ""
GSM gsmAccess;
GSM_SMS sms;
// GSM
boolean notConnected;
//char input;
//byte input2;
//char txtContent[200];
byte i = 1;
byte f = 0;
boolean sendit;
//char senderNumber[11];
const String stopp PROGMEM = "Stopp";
//SD
char numbers[11];
//char nmbr;
int l = 0;
//Optimizing
const char q PROGMEM = '\xe5'; // å
const char w PROGMEM = '\xe4'; // ä
const char e PROGMEM = '\xf6'; // ö
const char r PROGMEM = '\xc5'; // Å
const char t PROGMEM = '\xc4'; // Ä
const char y PROGMEM = '\xd6'; // Ö
void setup() {
// txtContent[0] = '\0';
i = 0;
pinMode(53, OUTPUT);
Serial.begin(115200);
// Serial.begin(4800);
Serial.println(F("Connecting to GSM..."));
notConnected = true;
while (notConnected) {
if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
notConnected = false;
}
else {
Serial.println(F("Not Connected"));
delay(1000);
}
}
Serial.println(F("GSM Ready"));
if (!SD.begin(4)) {
Serial.println(F("Error with SD card"));
return;
}
Serial.println(F("SD Ready"));
delay(1000);
Serial.println(F("Write your sms and end it with * and press Send"));
Serial.flush();
}
void loop() {
char txtContent[300];
if (Serial.available() > 0 && !sendit) {
byte input2;
input2 = (int)Serial.read();
txtContent[i] = (char)input2;
if (txtContent[i] == '{') {
txtContent[i] = q;
}
else if (txtContent[i] == '}') {
txtContent[i] = w;
}
else if (txtContent[i] == '|') {
txtContent[i] = e;
}
else if (txtContent[i] == '[') {
txtContent[i] = r;
}
else if (txtContent[i] == ']') {
txtContent[i] = t;
}
else if (txtContent[i] == ';') {
txtContent[i] = y;
}
i++;
if (input2 == '*') {
// Remove the * from text.
for (int j = 0; j < sizeof(txtContent); j++) {
if (txtContent[j] == '*') {
txtContent[j] = '\0';
//Serial.println(txtContent);
}
}
sendit = true;
Serial.flush();
}
else {
sendit = false;
Serial.flush();
}
}
else if (sendit && txtContent[0] != '\0') {
int txtCount = 0;
// else if(sendit){
Serial.println(F("Sending please wait..."));
// Serial.flush();
File myFile;
myFile = SD.open("numbers.txt");
char input;
if (myFile) {
// if (myFile.available()) {
while(myFile.available()){
input = (char)myFile.read();
if (input == ',') {
sms.beginSMS(numbers);
sms.print(txtContent);
// sms.beginSMS("0704941025");
// sms.print("yo");
delay(30);
sms.endSMS();
delay(30);
Serial.println(numbers);
Serial.flush();
// Serial.flush();
for (int j = 0; j < sizeof(numbers); j++) {
if (numbers[i] != '\0') {
numbers[j] = '\0';
}
}
f = 0;
}
else {
numbers[f] = input;
f++;
}
}
myFile.close();
Serial.println(F("All texts have been sent."));
Serial.flush();
} else {
Serial.println(F("error opening numbers.txt"));
}
for (int j = 0; j < sizeof(txtContent); j++) { // Clear text
txtContent[j] = '\0';
}
i = 0;
sendit = false;
}
else {
// delay(1000);
if (sms.available()) {
char senderNumber[11];
sms.remoteNumber(senderNumber, 11);
if (sms.peek() == 'S') {
Serial.print(F("Detta nummer har skickat Stopp: "));
Serial.println(senderNumber);
}
sms.flush();
Serial.flush();
// sendit = false;
}
}
}
Arduino is a strange ground for me but if that is anything like C, then i risk saying sizeof(numbers) will likely return 44, because you're asking for the size of an array in bytes, this probably means your for loop will iterate up to numbers[43] when numbers[] length is 11. Consider this instead:
for (int j = 0; j < sizeof(numbers)/sizeof(numbers[0]); j++) {
Same goes for all the other times you check for the size of an array in this code.
Also, do double check your textfile to ensure its really written in your expected format: 11 numbers then a comma, with no exception. You should maybe try to figure out if f went past 11 digits before hitting a comma and "Fail gracefully" with an error message.

Resources