I have a simple Arduino sketch which I have been playing with on my Uno.
The idea is simple, the user turns a potentiate (pin A2), when they pass a certain threshold a LED is turned on (pin 7).
Here is the code:
// Digital pins
const byte ledPin = 7;
// Analog pins
const byte userInputPotPin = A2;
// Potentiometer constants
const int userInputPotMinimumValue = 0;
const int userInputPotMaximumValue = 1023;
const int userInputMinimumValue = 1;
const int userInputMaximumValue = 100;
// Variables
const int threshold = 90;
void setup()
{
Serial.begin(9600);
// Digital pins
pinMode(ledPin, OUTPUT);
// Analog pins
pinMode(userInputPotPin, INPUT);
}
void loop()
{
int rawValue = analogRead(userInputPotPin);
int mappedValue = map(rawValue, userInputPotMinimumValue, userInputPotMaximumValue, userInputMinimumValue, userInputMaximumValue);
String messageText;
messageText += "Raw: " + String(rawValue) + "\t";
messageText += "Mapped:" + String(mappedValue);
if(mappedValue > threshold)
{
messageText += "\tThreshold exceeded!";
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
Serial.println(messageText);
delay(100);
}
The problem is that when it is run the hardware is very unresponsive - I can turn the pot, but I don't see the light change for several minutes. The log messages in the serial monitor also seem to be lagging behind.
I have tried:
* Removing the Serial statements (so there is no serial communication when the sketch is running), and just observing the LED. This makes no difference.
* Increasing the value in the delay up to 1000. This makes no difference in the responsiveness.
However, when I run the sketch on my Mega2560 the problem goes away and the circuit is as responsive as I expect.
Is there something wrong with my Uno board?
2 Answers 2
It turns out the problem was the A2 pin on the board.
When I used the A0 pin (or a different board) the problem goes away.
I realised something was wrong when I noticed the values from the pot were strange (I expected values in the range 0 - 1023, but was receiving values from 170-250 ish).
-
Btw, you can use the Arduino 'map' command to map a range to another range.Michel Keijzers– Michel Keijzers2020年02月05日 11:31:04 +00:00Commented Feb 5, 2020 at 11:31
The String+ operator is very expensive. High likely what it does is:
- Create a new block of memory to accommodate the old string content and the to-be-concatenated text.
- Copy the current String to a new string location
- Concatenate the string
- Free the old memory
Besides creating memory gaps which can be disastrous for the just 2 KB SRAM of the Arduino Uno, it takes a lot of time.
Some tips:
- Do not use Strings
- Do not concatenate strings if not needed
- To save more time, use short strings instead
If you really need to debug a time critical part, copy numbers you want to print to an array, and AFTER you do all 'real' code, start printing the numbers.
-
1Also there is no reason to concat strings for serial output. Just print the parts one after another. To get "Number: 5 bananas" you could use
Serial.print("Number: "); Serial.print(number_variable); Serial.println(" bananas")
chrisl– chrisl2020年02月04日 15:34:43 +00:00Commented Feb 4, 2020 at 15:34 -
@chrisl that's indeed my second tip.Michel Keijzers– Michel Keijzers2020年02月04日 15:41:05 +00:00Commented Feb 4, 2020 at 15:41
-
1Thanks for the excellent advice. Unfortunately I can't mark it as the answer to the question as my issue was caused by something else (see my answer).Hoppy– Hoppy2020年02月05日 11:24:41 +00:00Commented Feb 5, 2020 at 11:24
-
No problem, btw, you can accept your own answer too.Michel Keijzers– Michel Keijzers2020年02月05日 11:30:28 +00:00Commented Feb 5, 2020 at 11:30
Explore related questions
See similar questions with these tags.
void loop(){Serial.println(analogRead(A2));delay(100);}
?