Goal:
I want the variable tweet (which outputs either HIGH or LOW inside the void print() function) to turn on and off the LED_BUILTIN.
Restriction:
The if statement "producing" the tweet must run outside of the void loop().
Problem:
It seems that the void print() function does not return / expose the variable tweet inside the void loop(). The only thing what the serial monitor shows is Serial.println(val); which is 0.
What am I missing / misunderstanding here? Thank you for your help.
int intPressure = 11;
int tweet = 0;
int val = 0;
void setup() {
}
void print() {
if(intPressure != 0)
{
Serial.println("HIGH");
tweet = HIGH;
}
else
{
Serial.println("LOW");
tweet = LOW;
}
}
void loop() {
void print();
val = digitalRead(LED_BUILTIN);
digitalWrite(LED_BUILTIN, tweet);
Serial.println("---");
Serial.println(val);
Serial.println("---");
}
int intPressure = 12;
int tweet = 0;
int val = 0;
void setup() {
}
void print() {
if(intPressure != 0)
{
Serial.println("HIGH");
tweet = HIGH;
}
else
{
Serial.println("LOW");
tweet = LOW;
}
return tweet;
}
void loop() {
int tweetStatus = print();
val = digitalRead(LED_BUILTIN);
digitalWrite(LED_BUILTIN, tweetStatus);
Serial.println("---");
Serial.println(val);
Serial.println("---");
}
and got 2 error messages :
Error A:
In function 'void print()':
test_bed:21: error:
return-statement with a value, in function returning 'void' [-fpermissive]
return tweet;
^
Error B:
In function 'void loop()':
test_bed:26: error:
void value not ignored as it ought to be
int tweetStatus = print();
^
exit status 1
return-statement with a value, in function returning 'void' [-fpermissive]
Despite the explanations regarding the error messages below, I don't understand them quite, yet:
Error A It means a function is declared to return nothing (void) but you are assigning the return code to a variable.
Error B The error means that in your function: void* foo(...); You have a statement: return; But the compiler expects a value to be provided: return myVoidPtr;
I didn't realize that tweet was global. You don't need any return statement then and the function can be a void function. Just alter tweet in print and use it from loop. It will keep whatever value you last gave it. Global variables are available for use anywhere in your code.
And the global variable thing made me think about how to go on with the next problem, thank you.
I just tried to implement this code in another greater code block.
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
int tweet = 0;
int number = 1023;
Serial.print("data = ");
Serial.println(userData->pressure);
int intPressure = atoi(userData->pressure);
Serial.print("intPressure = ");
Serial.println(intPressure);
//if (*(userData->pressure) == number) // ==number brings HIGH and !=number brings LOW
int print() {
if(intPressure != 0)
{
Serial.println("HIGH");
tweet = HIGH;
}
else
{
Serial.println("LOW");
tweet = LOW;
}
return tweet;
}
void loop() {
int tweetStatus = print();
val = digitalRead(LED_BUILTIN);
// tweetStatus makes LED_BUILTIN either HIGH or LOW
digitalWrite(LED_BUILTIN, tweetStatus);
Serial.println("---");
Serial.println(val);
Serial.println("---");
...
}
The output is the following error message:
test_bed: In function 'void printUserData(const UserData*)':
test:175: error: a function-definition is not allowed here before '{' token
^
test_bed:239: error: expected '}' at end of input
^
exit status 1
a function-definition is not allowed here before '{' token
According to the error above, you cannot place the function int(print(){} ) inside the function void printUserData(const struct UserData* userData){}. Generally speaking, you cannot put a function inside a function. I chose the if statement if(intPressure != 0)|{} to be inside the void printUserData function because I wanted this if statement to use the variable int intPressure = atoi(userData->pressure); . This variable decides about whether the LED_BUILTIN is LOW or HIGH.
Maybe one way to solve this is to makeint intPressure = atoi(userData->pressure); to a global variable, so that it can be easily accessed by any function, particularly the void loop() function? This way, I could also just move the If statement if(intPressure != 0)|{} to the void loop() function. If this a good way to go, how would you do that?
You already have a global variable named intPressure. I'm not sure I understand what you are getting at.
Perhaps you should go to google and search for "C++ variable scope" and read some of the articles it finds. I think that may help to clear up some of your confusion.
Also, personally, I would not name a function that I wrote 'print'. It appears to be a keyword in Arduino. At least the IDE makes it a different color and that makes me nervous.
gfvalvo:
Also, personally, I would not name a function that I wrote 'print'. It appears to be a keyword in Arduino. At least the IDE makes it a different color and that makes me nervous.
Whether or not the IDE makes a word orange has nothing to do with its being a keyword or not. It only means that it is listed in a keywords.txt file in some library. The only purpose is to make some words turn orange. It serves no other real purpose. What's worse is that the library only needs to be in your folder to have this effect. It happens even for libraries not included in the current code. If you want the colors of words to actually mean anything, then you have to use a more grown-up IDE like Eclipse.
Yeah but way too many library writers try to claim really common terms for themselves. I could write a library with a dictionary and you'd have to start picking random strings of letters.
If the IDE only did the orange thing for libraries included in the current sketch then I'd be a little more apt to agree. But it doesn't. It pulls any file it can find with that name and starts just willy-nilly orangish all the words it finds and that gets confusing. One of the big reasons I don't use the IDE to write my code.
Clarification of my 2nd problem:
I wanted to make the local variable tweet from function printUserData to a global variable so this local variable can be accessed by the void loop() function. I learned that this is not a good practice, making local variables to global ones:
New programmers are often tempted to use lots of global variables, because they are easy to work with, especially when many functions are involved. However, use of non-const global variables should generally be avoided altogether!
In order to make a variable from another function available inside the void loop() function you may do the following:
I am using the data type byte to make tweet as a byte variable. Inside the printUserData function tweet will return the value also to the void loop function(), since its stored inside byte tweet. This worked for me.
Since you don't call your print function anywhere in loop, no you're not going to get the value of tweet from that function here. Here you have another local variable in loop that just happens to have the same name, tweet, as the local variable in the print function. But the two have absolutely nothing to do with one another. So when you call that digitalWrite tweet will still be 0 and the led will always be off.
Now you might have this in loop:
tweet = print();
and that will call print and return the value of tweet from print and store it in the tweet variable in loop.
New programmers are often tempted to use lots of global variables, because they are easy to work with, especially when many functions are involved. However, use of non-const global variables should generally be avoided altogether!
That's good advise for bigger programs. But for most Arduino code it is safely ignored advise. Typically these projects are written by one or two people and are small enough to tell when you shadow a variable. Sure, it's better to avoid globals, but I wouldn't get too bent out of shape about getting rid of them all. They're not going to hurt most of the time.
0011:
According to the error above, you cannot place the function int(print(){} ) inside the function void printUserData(const struct UserData* userData){}. Generally speaking, you cannot put a function inside a function.
Absolutely correct. And yet in your current code you are still doing ...
byte printUserData(const struct UserData* userData) {
byte tweet = 0; // will return the value of this variable
Serial.print("data = ");
Serial.println(userData->pressure);
int intPressure = atoi(userData->pressure);
int print() {
....
Can you explain why you're still doing this, when way back in your reply #6 you so clearly told us that you understood that you cannot?
Dude, by seeing the code you have provided I can tell you that you have forgotten to start the serial communication, Serial.begin(9600);
Second mistake, you must call the function. Calling a function means to "trigger" it.
Example:
void setup(){
}
void loop(){
int x =0;
if( x==0){
cheesecake(); //cheesecake() calls the
//function called cheesecake
}
}
void cheesecake(){
//after calling cheesecake you come here
//here do whatever you want
}