I am a few days into programming with Arduino and I've run into an annoying problem. My circuit contains three LEDs connected to pins 2,3,4 and a push button connected to pin 8. What I want to do is alternate the lit LED by pressing the button. I'm using a variable to count which LED is lit at a certain point and resets when it reaches the value 4. The hardware part works fine, because I've tested it separately (automated alternation of the LEDs and the button example program in the Arduino IDE), so there has to be something with my code. What is it exactly?
void setup(){
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(8, INPUT);
}
void loop(){
int buton= digitalRead(8);
int led = 1;
if(led == 1){
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
if(led == 2){
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
}
if(led == 3){
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
}
if(buton == HIGH){
led++;
if(led == 4) led = 1;
}
}
I know for a fact that it doesn't enter the last if (the one for the button input value) because I've placed a Serial.println() to see both the value of variable led and a constant string and it didn't show.
Thank you in advance!
Smilledge was right in the comments, the led variable was reset to 1 at every iteration of the loop. I wasn't aware you could have variable declarations outside the two functions (setup and loop), so I just made the variable global.
Related
I am trying to figure out how to run 2 while loops at the same time but in the easiest way possible?
I want one loop to check for a signal from the joystick that i connected to the Arduino.I want the second loop to display a face in the LCD screen and i want it to blink every 5 minutes.(I know it sounds weird)
The term you are looking for here is called multi-threading. The first thread will be for your joystick loop and the second will be fore your LCD screen. Depending on the board you are using, the strain added to the hardware will be different.
Regardless of board type, you can use a library such as protothreads to accomplish this. Here is the code from Digikey's tutorial on multithreading in arduino programs.
#include "protothreads.h"
#define LED_1 2
#define LED_2 3
pt ptSlowBlink;
pt ptFastBlink;
int fastBlinkThread(struct pt* pt)
{
PT_BEGIN(pt);
while(true)
{
digitalWrite(LED_1, HIGH);
PT_SLEEP(pt, 250);
digitalWrite(LED_1, LOW);
PT_SLEEP(pt, 250);
}
PT_END(pt);
}
int slowBlinkThread(struct pt* pt)
{
PT_BEGIN(pt);
while(true)
{
digitalWrite(LED_2, HIGH);
PT_SLEEP(pt, 1000);
digitalWrite(LED_2, LOW);
PT_SLEEP(pt, 1000);
}
PT_END(pt);
}
void setup()
{
PT_INIT(&ptSlowBlink);
PT_INIT(&ptFastBlink);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
}
void loop()
{
PT_SCHEDULE(slowBlinkThread(&ptSlowBlink));
PT_SCHEDULE(fastBlinkThread(&ptFastBlink));
}
If the board you're using support Mbed OS, then there are also native features that will provide a significant increase in performance over the code above. It comes with some added learning curve but if you want to learn more the above tutorial also has a small introduction to Mbed OS multithreading.
I'm trying to use encoders to track the movement of three wheels on a robot, but as soon as any of the motors move the robot "locks up", it stops responding to commands, stops printing to the serial monitor, and just keeps spinning its wheels until I turn it off. I cut out everything except just the code to track one encoder and tried turning the wheel by hand to sus out the problem, but it still locked up. And even more strangely, now it will start spinning one of the wheels even though I've removed any code that should have it do that, even by mistake.
I used the Arduino IDE to program the pico since I've got no familiarity with python, but I can't find any information or troubleshooting tips for using interrupts with the pico that don't assume you're using micropython.
Here's the simplified code I'm using to try to find the problem. All it's meant to do is keep track of how many steps the encoder has made and print that to the serial monitor every second. Ive tried removing the serial and having it light up LEDs instead but that didn't help.
int encA = 10;
int encB = 11;
int count = 0;
int timer = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(encA),readEncoder,RISING);
timer = millis();
}
void loop() {
// put your main code here, to run repeatedly:
if (timer - millis() > 5000) {
Serial.println(count);
timer = millis();
}
}
void readEncoder() {
int bVal = digitalRead(encB);
if (bVal == 0) {
count--;
}
else{
count++;
}
}
Does the mapping function digitalPinToInterrupt for the Pi Pico work?
Can you try just using the interrupt number that corresponds to the pi?
attachInterrupt(9,readEncoder,RISING); //Or the number 0-25 which maps to that pin
https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__irq.html
You have the wrong pin to encoder in your example (maybe you incorrectly copy and pasted)?
attachInterrupt(digitalPinToInterrupt(**encA**),readEncoder,RISING);
void readEncoder() {
int bVal = digitalRead(**encB**); ...}
There is similar code on GitHub that you could modify and try instead.
https://github.com/jumejume1/Arduino/blob/master/ROTARY_ENCODER/ROTARY_ENCODER.ino
It might help you find a solution.
Also,
https://www.arduino.cc/reference/en/libraries/rpi_pico_timerinterrupt/
The interrupt number corresponds to the pin (unless you have reassigned it or disabled it) so for pin 11 the code can be:
attachInterrupt(11, buttonPressed, RISING);
This works:
bool buttonPress = false;
unsigned long buttonTime = 0; // To prevent debounce
void setup() {
Serial.begin(9600);
pinMode(11, INPUT_PULLUP);
attachInterrupt(11, buttonPressed, RISING);
// can be CHANGE or LOW or RISING or FALLING or HIGH
}
void loop() {
if(buttonPress) {
Serial.println(F("Pressed"));
buttonPress= false;
} else {
Serial.println(F("Normal"));
}
delay(250);
}
void buttonPressed() {
//Set timer to work for your loop code time
if (millis() - buttonTime > 250) {
//button press ok
buttonPress= true;
}
buttonTime = millis();
}
See: https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__irq.html for disable, enable etc.
let me describe as following:
class foo{
public:
[...]
digitalWrite(uint8_t pin, uint8_t function){
digitalWrite(CS_PIN, LOW); // <<== CALLS foo::digitalWrite(...
delayMicroseconds(1);
SPI.beginTransaction(settings);
SPI.transfer16(this->m_txFrame);
SPI.endTransaction();
digitalWrite(CS_PIN, HIGH); // <<== CALLS foo::digitalWrite(...
}
[...]
};`
For that Arduino has no encapsilation for digitalWrite, the beaviour ist as expected. Is there another solution except renaming foo:digitalWrite(...) I do not know yet?
Thanks in advance!
Joerg
İt's a simple basic thing in which i have my arduino connected to a HC-06 bluetooth. The point is to control switch on/off led pin with my phone. Here's the code :
int ledPin = 13;
int state = 0;
int flag = 0;
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
}
void loop() {
if(Serial.available() >0) {
state = Serial.read();
flag = 0;
}
if(state == '0') {
digitalWrite(ledPin, LOW);
Serial.println("LED: off");
flag = 1;
}
}
else if (state == '1') {
Serial.println("LED: on");
flag = 1;
}
}
I don't think it might have much relevance. Whenever i try to upload the code it gives me the following error:
avrdude stk500_recv() programmer is not responding
avrdude stk500_getsync() attempt # of 10 not in sync resp=0x00
Any idea why and how i might solve it. Thnx in advance!Douglas
I guess that there is a conflict between the USB/Serial and HC06/Serial.
You can solve this issue by using the Software Serial library and connect the HC06 to other pins. You can find an example here on how to use the library.
Unplug the rx and tx pins and keep in power and ground while uploading. When these pins are connected it interferes with the program's ability to upload. If this is in fact the problem then once the program is uploaded you can reattach rx and tx. Now you should be able to properly pair to your device.
Please disconnect the Tx and RX pin from Arduino before uploading and connect it after uploading the code. Otherwise, it will show an error
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have a RFID reader which is connected to the Arduino.. and successfully receives tag number to serial monitor. But when I put the LED blink inside the loop, then the rfid reading is delayed: it receives tag numbers one by one after each blink.
Code is below. I think I should use multi-threading or interrupts, but I don't know how to do it.
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
pinMode(2, OUTPUT);
}
void loop() {
// blink led in pin 2
digitalWrite(2, HIGH);
delay(1000);
digitalWrite(2, LOW);
delay(1000);
//Below Serial1.available() checks my rfid reader input signal and print on serial monitor of Arduino.. and Serial1 is on pin RX1 19 (RX1 19 is the default pin for serial1 defined by Arduino developers "http://arduino.cc/en/reference/serial#.Uyvbq6iSzIg") to which my rfid reader is connected
if (Serial1.available()) {
int i = Serial1.read();
Serial.print(i);
}
}
There is an Arduino file called "Blink without Delay" It is included with the Arduino examples and I have linked to it. Do yourself a favor and take ten minutes to read through the tutorial and the code in order to understand what it does.
You can use the timer of the Arduino and the appropriate interrupts. So something like this here:
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
pinMode(2, OUTPUT);
/* Initialize timer, e.g. timer1 */
noInterrupts(); //disable interrupts
TCCR1A = 0; //Timer1 control register A
TCCR1B = 0; //Timer1 control register B
TCNT1 = 0; //Counter of timer1
OCR1A = 15625; //Timer1 compare match register
TCCR1B |= (1<<WGM12); //Set timer1 in CTC mode
/* Define prescaler with 1024. If the clock is 16 MHz, then timer1 will run
* with 16 MHz / 1024 = 15625 Hz --> 64 us, to get one second, we
* need 15625 cycles, which is the OCR1A register */
TCCR1B |= (1<<CS10) | (1<<CS12); // clock prescaler = 1024
TIMSK1 |= (1<<OCIE1A); //enable timer compare interrupt
interrupts(); //enable interrupts
}
//This routine is called every time, timer1 counter reaches the compare register
ISR(Timer1_COMPA_vect) {
digitalWrite(2, digitalRead(2) ^ 1); //toggle LED
}
//the loop
void loop() {
if (Serial1.available()) {
int i = Serial1.read();
Serial.print(i);
}
}