Unable to compile arduino code in platfromio - arduino

I am unable to compile bellow code in platfromIO.
But which is successfully compiled in arduino 1.5 IDE
#define PRESSED LOW
#define NOT_PRESSED HIGH
const byte led = 13;
#define shortPress 100
#define longPress 500
long blinkInterval = 500;
unsigned long previousBlink=0;
bool ledState = true;
bool blinkState = true;
typedef struct Buttons {
const byte pin = 2;
const int debounce = 10;
unsigned long counter=0;
bool prevState = NOT_PRESSED;
bool currentState;
} Button;
// create a Button variable type
Button button;
void setup() {
pinMode(led, OUTPUT);
pinMode(button.pin, INPUT_PULLUP);
}
void loop() {
// check the button
button.currentState = digitalRead(button.pin);
// has it changed?
if (button.currentState != button.prevState) {
delay(button.debounce);
// update status in case of bounce
button.currentState = digitalRead(button.pin);
if (button.currentState == PRESSED) {
// a new press event occured
// record when button went down
button.counter = millis();
}
if (button.currentState == NOT_PRESSED) {
// but no longer pressed, how long was it down?
unsigned long currentMillis = millis();
//if ((currentMillis - button.counter >= shortPress) && !(currentMillis - button.counter >= longPress)) {
if ((currentMillis - button.counter >= shortPress) && !(currentMillis - button.counter >= longPress)) {
// short press detected.
handleShortPress();
}
if ((currentMillis - button.counter >= longPress)) {
// the long press was detected
handleLongPress();
}
}
// used to detect when state changes
button.prevState = button.currentState;
}
blinkLED();
}
void handleShortPress() {
blinkState = true;
ledState = true;
blinkInterval = blinkInterval / 2;
if (blinkInterval <= 50)
blinkInterval = 500;
}
void handleLongPress() {
blinkState = false;
ledState = false;
}
void blinkLED() {
// blink the LED (or don't!)
if (blinkState) {
if (millis() - previousBlink >= blinkInterval) {
// blink the LED
ledState = !ledState;
previousBlink = millis();
}
} else {
ledState = false;
}
digitalWrite(led, ledState);
}
Here is the platformio.ini
[env:attiny13]
platform = atmelavr
board = attiny13
framework = arduino
Compile output of PIO
Processing attiny13 (platform: atmelavr; board: attiny13; framework: arduino)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/attiny13.html
PLATFORM: Atmel AVR 1.15.0 > Generic ATtiny13
HARDWARE: ATTINY13 1MHz, 64B RAM, 1KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.2
LDF: Library Dependency Finder -> xxxxxx
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Compiling .pio/build/attiny13/src/Blink.cpp.o
src/Blink.cpp: In function 'void setup()':
src/Blink.cpp:33:23: error: 'INPUT_PULLUP' was not declared in this scope
pinMode(button.pin, INPUT_PULLUP);
^
*** [.pio/build/attiny13/src/Blink.cpp.o] Error 1
============================================================================ [FAILED] Took 1.31 seconds
The terminal process terminated with exit code: 1
Terminal will be reused by tasks, press any key to close it.
Do I need to amend the code for PlatromIO ?
However when I comment on the INPUT_PULLUP line. I am able to compile in PIO but output binary size is higher with compared to Arduino IDE ?
Can you suggest any flags or configurations to optimize the binary size ?

Related

I am creating this temp monitoring system

I am creating this temp monitoring system...Therefore, i want to get messages/alerts when the temperature are below 6 and again when they come back to above 6. Note: I don't want the alert (sendMailNormalValue():wink: to come when the system boots up....How do I deactivate the sendMailNormalValue(); and activate it only when the temp are below 6 (only to alert me when comes back to above 6)..
#include <OneWire.h>
#include <DallasTemperature.h>
// GPIO where the DS18B20 is connected to
const int oneWireBus = 5;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
//========================================
float t;
int period = 30000;
unsigned long time_now = 0;
bool DisplayFirstTime = true;
int period1 = 30000;
unsigned long time_now1 = 0;
void sendMailBelowValue(){
}
void sendMailNormalValue(){
}
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
}
void loop() {
// put your main code here, to run repeatedly:
sensors.requestTemperatures();
t = sensors.getTempCByIndex(0);
float p=t-2;
// Check if any reads failed and exit early (to try again).
if (isnan(t)) {
Serial.println("Failed to read from sensor !");
delay(500);
return;
}
if (t>6){
if(millis() > time_now + period){
time_now = millis();
sendMailNormalValue();
Serial.print ("You got messagae");
}
}
if (t<6){
if(millis() > time_now1 + period1 || DisplayFirstTime){
DisplayFirstTime = false;
time_now = millis();
sendMailBelowValue();
}
}
}
I think I understand what you mean. On error (temp < 6), you want to send an email every 30 seconds; when the teperature reaches 6 or mode, send a single email to say the error condition has been fixed. On boot, only send an email if in error.
If that's it, you'll need to keep track of the error condition using a global flag.
// ...
bool tempError; // initialized in setup()
void setup()
{
// ...
float t;
for(;;) // loop until we get a valid reading.
{
t = sensors.getTempCByIndex(0);
if (!isnan(t))
break;
Serial.println("Failed to read from sensor !");
delay(500);
}
tempError = (t < 6);
}
void loop()
{
// read temp and check sensor...
// ...
if (t < 6)
{
tempError = true;
// send error email, set timer, etc...
}
else if (tempError)
{
// temp is now fine, after being too low.
tempError = false; // Clear error flag.
// send OK email, only once.
// Don't forget to clear the 30 second email timer !!!
}
}
Usually, you'd want some hysteresis in an alert system. You should consider waiting some seconds after the temperature has been 'fixed' before sending the 'OK' email. Otherwise you may end up getting lots of fail/fixed emails when the temperature is around 6 degrees. This is usually done with a simple state machine engine, but that is a bit beyond the scope of this questkon.

Arduino interrupt button calls multiple ISRs

For a project I'm using an Arduino Mega2560 to control a couple of stepper motors with the AccelStepper library. It's the first time I'm using Arduino and I'm writing everything in Arduino IDE 2.0 (I also tried it with IDE 1.8 but no change). It's coming along quite nicely and it's a lot of fun! Everything seems to work as intended. Except for 1 thing.
I'm using 4 buttons to trigger certain events in my code, using the interrupt function. I'm doing this because the accelStepper library asks a lot of proccesing from the arduino and I need as many steps/sec as I can get. When 1 of the interrupts is activated it somehow calls another with it. I've removed everything from the code except the interrupt part to see if just the interrupts would work, but I still have the same issue. With this code I would expect to see a print in the serial of the button I pressed. However, when I press button one it sometimes prints both button 1 and button 2. When I press button 2 it always calls button 1 as well. Sometimes button 1 is printed first, sometimes button 2 is printed first. When I press button 3, button 2 is always called and when I press button 4, button 3 is always called.
As you can see in the code, I'm using port 18 through 21 as interrupt ports and their grounds are all connected to the same GND port on the Arduino. I tried disconnecting all the grounds and only connected button 1 with the Arduino GND. But somehow it still triggers button 2 as long as the cable of the button is still plugged into pin 19. Even though the ground of button 2 is not connected.
What am I doing wrong? Did I misunderstand how the interrupts with input_pullup works? Or am I doing something wrong in my code?
I'm running out of ideas so any help is appreciated!
// Define pins numbers
const int button1 = 18;
const int button2 = 19;
const int button3 = 20;
const int button4 = 21;
// Define variables
volatile bool button1Pressed = false;
volatile bool button2Pressed = false;
volatile bool button3Pressed = false;
volatile bool button4Pressed = false;
float timeTrigger1 = 0;
float timeTrigger2 = 0;
float timeTrigger3 = 0;
float timeTrigger4 = 0;
void setup() {
Serial.begin(9600);
Serial.println("Startup begins");
pinMode(button1, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button1), interrupt1, FALLING);
pinMode(button2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button2), interrupt2, FALLING);
pinMode(button3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button3), interrupt3, FALLING);
pinMode(button4, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button4), interrupt4, FALLING);
Serial.println("Startup finished");
}
void loop() {
if (button1Pressed) {
Serial.println("button 1 was pressed");
button1Pressed = false;
}
if (button2Pressed) {
Serial.println("button 2 was pressed");
button2Pressed = false;
}
if (button3Pressed) {
Serial.println("button 3 was pressed");
button3Pressed = false;
}
if (button4Pressed) {
Serial.println("button 4 was pressed");
button4Pressed = false;
}
}
void interrupt1() {
if (millis() - timeTrigger1 >= 500) {
timeTrigger1 = millis();
button1Pressed = true;
}
}
void interrupt2() {
if (millis() - timeTrigger2 >= 500) {
timeTrigger2 = millis();
button2Pressed = true;
}
}
void interrupt3() {
if (millis() - timeTrigger3 >= 500) {
timeTrigger3 = millis();
button3Pressed = true;
}
}
void interrupt4() {
if (millis() - timeTrigger4 >= 500) {
timeTrigger4 = millis();
button4Pressed = true;
}
}
EDIT: checking the button state once the ISR is called did the trick. Like the code below.
void interrupt1() {
if (millis() - timeTrigger1 >= 500 && digitalRead(button1)==LOW) {
timeTrigger1 = millis();
button1Pressed = true;
}
}

ESP32 - Multi Tasking with while in a task

I try to build a chrono laser with two ESP32 and two LDR.
I have two ESP32:
One do a ACCESS Point with a LDR
Second connect to the AP, have the algorithm of the laser chrono and a second LDR
In the second one, i try also to have a WebServer so i can connect with my phone and restart the chrono.
I try to do multitasking but everytime my ESP32 restart :
18:10:42.625 -> E (5775) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
18:10:42.672 -> E (5775) task_wdt: - IDLE0 (CPU 0)
18:10:42.672 -> E (5775) task_wdt: Tasks currently running:
18:10:42.672 -> E (5775) task_wdt: CPU 0: Task1
18:10:42.672 -> E (5775) task_wdt: CPU 1: Task2
18:10:42.672 -> E (5775) task_wdt: Aborting.
18:10:42.672 -> abort() was called at PC 0x400d9033 on core 0
You can find my code here:
https://create.arduino.cc/editor/marcoberle/c4762636-36c6-4551-92f2-935021a001c9/preview
My code :
// Load Wi-Fi library
#include <WiFi.h>
#include <HTTPClient.h>
//Declaration of PIN
const int departReceiver = 4; // the number of the pin
const int LED_BUILTIN = 2;
// Replace with your network credentials
const char* ssid = "ESP32-ARRIVE";
const char* password = "123456789";
// Set web server port number to 80
WiFiServer server(80);
WiFiClient client = server.available();
//Your IP address or domain name with URL path
const char* serverNameArrive = "http://192.168.4.1/arrive";
// Variable to store the HTTP request
String header;
// Auxiliar variables to store the current output state
String output26State = "off";
String output27State = "off";
// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;
// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;
TaskHandle_t Task1;
TaskHandle_t Task2;
void setup() {
Serial.begin(115200);
pinMode(departReceiver, INPUT);
// Initialize the output variables as outputs
pinMode(output26, OUTPUT);
pinMode(output27, OUTPUT);
// Set outputs to LOW
digitalWrite(output26, LOW);
digitalWrite(output27, LOW);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
client = server.available();
//create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
6, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
delay(500);
//create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task2code, /* Task function. */
"Task2", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
7, /* priority of the task */
&Task2, /* Task handle to keep track of created task */
1); /* pin task to core 1 */
delay(500);
}
//CHRONO VAR
unsigned int departStatus = 0;
unsigned int arriveStatus = 0;
unsigned int start_time = 0;
unsigned int stop_time = 0;
unsigned int total_time = 0;
const unsigned int OFF = 0;
const unsigned int ON = 1;
String httpGETRequest(const char* serverName) {
HTTPClient http;
// Your IP address with path or Domain name with URL path
http.begin(serverName);
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "--";
if (httpResponseCode > 0) {
payload = http.getString();
}
else {
}
// Free resources
http.end();
return payload;
}
String ChronoLog = "";
int reset = 0;
void Chrono () {
if (reset == 0) {
reset = 1;
ChronoLog = "<p>ALGO START</p>";
Serial.println("ALGO START");
while (departStatus == OFF) {
departStatus = digitalRead(departReceiver);
}
ChronoLog += "<p>Borne de début prête</p>";
Serial.println("Borne de début prête");
while (arriveStatus == OFF) {
arriveStatus = httpGETRequest(serverNameArrive).toInt();
}
ChronoLog += "<p>Borne de fin prête</p>";
ChronoLog += "<p>En attente du courreur</p>";
Serial.println("Borne de fin prête");
Serial.println("En attente du courreur");
while (departStatus == ON) {
departStatus = digitalRead(departReceiver);
}
ChronoLog += "<p>Courreur en place</p>";
Serial.println("Courreur en place");
digitalWrite(LED_BUILTIN, HIGH);
while (departStatus == OFF) {
departStatus = digitalRead(departReceiver);
}
ChronoLog += "<p>Chrono lancé</p>";
Serial.println("Chrono lancé");
start_time = millis();
while (arriveStatus == ON) {
arriveStatus = httpGETRequest(serverNameArrive).toInt();
}
stop_time = millis();
total_time = stop_time - start_time;
ChronoLog += "<p>Courru en </p>";
float timeSe = total_time * 0.001;
//ChronoLog += "<p><b>" + String(timeSe) + "</b></p>" ;
Serial.println("Courru en");
Serial.println(timeSe);
}
}
void ResetChrono () {
reset = 0;
departStatus = 0;
arriveStatus = 0;
start_time = 0;
stop_time = 0;
total_time = 0;
}
void Webserver() {
// Listen for incoming clients
client = server.available();
if (client) { // If a new client connects,
currentTime = millis();
previousTime = currentTime;
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
currentTime = millis();
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
//RESET CHRONO
if (header.indexOf("GET /RESET") >= 0) {
ResetChrono();
}
// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
output26State = "on";
digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
output26State = "off";
digitalWrite(output26, LOW);
} else if (header.indexOf("GET /27/on") >= 0) {
Serial.println("GPIO 27 on");
output27State = "on";
digitalWrite(output27, HIGH);
} else if (header.indexOf("GET /27/off") >= 0) {
Serial.println("GPIO 27 off");
output27State = "off";
digitalWrite(output27, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
//Chrono(client);
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #555555;}</style></head>");
// Web Page Heading
client.println("<body><h1>CHRONO</h1>");
client.println(ChronoLog);
client.println("<p><button class=\"button\">RESET</button></p>");
// Display current state, and ON/OFF buttons for GPIO 26
client.println("<p>GPIO 26 - State " + output26State + "</p>");
// If the output26State is off, it displays the ON button
if (output26State == "off") {
client.println("<p><button class=\"button\">ON</button></p>");
} else {
client.println("<p><button class=\"button button2\">OFF</button></p>");
}
// Display current state, and ON/OFF buttons for GPIO 27
client.println("<p>GPIO 27 - State " + output27State + "</p>");
// If the output27State is off, it displays the ON button
if (output27State == "off") {
client.println("<p><button class=\"button\">ON</button></p>");
} else {
client.println("<p><button class=\"button button2\">OFF</button></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
//Task1code: blinks an LED every 1000 ms
void Task1code( void * pvParameters ){
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
for(;;){
Chrono();
}
}
//Task2code: blinks an LED every 700 ms
void Task2code( void * Parameters ){
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());
for(;;){
Webserver();
}
}
void loop() {
}
Do you have any suggestion to optimize my code or a solution to not have the problem anymore ?
You're getting watchdog timer resets. That means your code has been running for too long without resetting a timer that's used to recover from crashes and infinite loops. This timer is handled automatically by the underlying code in the Arduino Core.
Your Chrono and Webserver tasks simply won't work the way you've written them. They never yield the processor. The ESP32 does not do multitasking the way Linux or Windows does. Multitasking on the ESP32 is non-preemptive. A task runs until it says "okay, I've done enough, someone else can run now". These two tasks never do that, so the watchdog timer goes off. Even if the watchdog timer didn't go off, this wouldn't work because nothing else would get the chance to run.
At the least you need to yield the processor in each of the tasks:
for(;;){
Chrono();
}
should be:
for(;;){
Chrono();
delay(1);
}
and
for(;;){
Webserver();
}
should be
for(;;){
Webserver();
delay(1);
}
Your code also has a lot of places where you do things like this:
while (departStatus == OFF) {
departStatus = digitalRead(departReceiver);
}
If departStatus stays OFF for too long, this will trigger the watchdog timer.
Any time you have a loop like this you need to make sure that the underlying system has a change to run once in a while.
Rewrite every single while loop that you have that's like that to call delay(1); - that will give the Arduino Core a chance to reset the watchdog timer.
Like so:
while (departStatus == OFF) {
departStatus = digitalRead(departReceiver);
delay(1);
}
I try a method i found on the web, and it's works.
Add libraries :
#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
Create a method:
void feedthedog () {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed = 1;
TIMERG0.wdt_wprotect = 0;
}
Add execution of the method in every while
while (departStatus == OFF) {
feedthedog();
departStatus = digitalRead(departReceiver);
}
I can wait, refresh page on the webserver, i don't get error :
19:38:40.321 -> Task1 running on core 0
19:38:40.321 -> ALGO START
19:39:20.937 -> Borne de début prête
19:39:39.093 -> Borne de fin prête
19:39:39.093 -> En attente du courreur
19:39:39.140 -> Courreur en place
19:39:51.840 -> Chrono lancé
19:39:58.804 -> Courru en
19:39:58.804 -> 6.99
19:39:58.804 -> Tâche fini
I put my update code here:
https://create.arduino.cc/editor/marcoberle/cb88dff8-d56c-422d-9f2e-4011ea2b80f4/preview

Arduino script throws error "X was not declared in this scope"

Code and scheme from this link: https://www.makerspaces.com/15-simple-arduino-uno-breadboard-projects/
I'm a total beginner. I just started and I had some difficulties with the board, my PC isn't recognising the board and I wanted to create a simple circuit to test some commands, to see if I solved the problem
Full code:
// Pin assignement
#define btnPin 7
#define led1Pin 8
#define led2Pin 9
#define led3Pin 10
enum fcnMode {
OFF,
LED1,
LED2,
LED3,
FADE1,
ALL,
BLINK,
NBSTATE
}; // OFF = 0 and NBSTATE=7
int ledState1 = LOW,ledState2 = LOW,ledState3 = LOW; // ledState used to set the LED
unsigned long buttonState = 0;
int funcState=0;
unsigned long currentMillis1,currentMillis2,currentMillis3; // will store current time
unsigned long previousMillis1,previousMillis2,previousMillis3; // will store last time LED was updated
const long interval1 = 100; // interval at which to blink (milliseconds)
const long interval2 = 300;
const long interval3 = 500;
/******************************************************************\
* PRIVATE FUNCTION: setup
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Initiate inputs/outputs
*
\******************************************************************/
void setup(){
Serial.begin(9600); // initialize serial port
pinMode(btnPin,INPUT_PULLUP);
pinMode(led1Pin,OUTPUT);
pinMode(led2Pin,OUTPUT);
pinMode(led3Pin,OUTPUT);
}
/******************************************************************\
* PRIVATE FUNCTION: loop
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Main Function of the code
\******************************************************************/
void loop(){
buttonPressed();
setMode();
}
/******************************************************************
* SUBFUNCTIONS
\******************************************************************/
void buttonPressed() {
buttonState = pulseIn(btnPin,HIGH,1000000);
if (buttonState > 50){
funcState += 1;
Serial.print("Button state n: ");
Serial.println(funcState);
}
funcState=funcState%NBSTATE;
}
void setMode() {
// All Off
digitalWrite(led1Pin,LOW);
digitalWrite(led2Pin,LOW);
digitalWrite(led3Pin,LOW);
Serial.print("Function : ");
Serial.println(funcState);
switch(funcState){
case OFF:
break;
case LED1:
digitalWrite(led1Pin,HIGH);
break;
case LED2:
digitalWrite(led2Pin,HIGH);
break;
case LED3:
digitalWrite(led3Pin,HIGH);
break;
case FADE1:
fade1();
break;
case ALL:
digitalWrite(led1Pin,HIGH);
digitalWrite(led2Pin,HIGH);
digitalWrite(led3Pin,HIGH);
break;
case BLINK:
blinkLed1();
blinkLed2();
blinkLed3();
break;
}
}
void fade1(){
int brightness = 0;
int fadeAmount = 5;
for (brightness=0;brightness<=255;brightness+=fadeAmount){
analogWrite(led1Pin, brightness);
delay(30);
}
for (brightness=255;brightness>=0;brightness-=fadeAmount){
analogWrite(led1Pin, brightness);
delay(30);
}
}
void blinkLed1(){
currentMillis1 = millis();
if (currentMillis1 - previousMillis1 >= interval1) {
// save the last time you blinked the LED
previousMillis1 = currentMillis1;
// if the LED is off turn it on and vice-versa:
if (ledState1 == LOW) {
ledState1 = HIGH;
} else {
ledState1 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(led1Pin, ledState1);
}
}
void blinkLed2(){
currentMillis2 = millis();
if (currentMillis2 - previousMillis2 >= interval2) {
// save the last time you blinked the LED
previousMillis2 = currentMillis2;
// if the LED is off turn it on and vice-versa:
if (ledState2 == LOW) {
ledState2 = HIGH;
} else {
ledState2 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(led2Pin, ledState2);
}
}
void blinkLed3(){
currentMillis3 = millis();
if (currentMillis3 - previousMillis3 >= interval3) {
// save the last time you blinked the LED
previousMillis3 = currentMillis3;
// if the LED is off turn it on and vice-versa:
if (ledState3 == LOW) {
ledState3 = HIGH;
} else {
ledState3 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(led3Pin, ledState3);
}
}
Error:
sketch_may09b.cpp: In function 'void setup()':
sketch_may09b:38: error: 'INPUT_PULLUP' was not declared in this scope
Your file extension is .cpp. I think it should be .ino if you are in Arduino IDE. If it doesn't help try just INPUT and add a pullup resistor to your button.

Problem with interruptions in Arduino Uno

I work with interruptions in Arduino UNO. In this project, I want to when the Door is opened the LED blink 10 times, and when the door is closed again, stop blinking the LED and exit the function. But in this code the LED only turn on and off once and it does not flash again.
My other problem is that, when the door is opened or closed, sometimes the opened or closed word appears several times in the Series monitor.
const byte LED_Red = 13;
const byte DOOR_SENSOR = 2; // magnetic door sensor pin
volatile int SensorState = LOW; // 0 close - 1 open wwitch
void setup()
{
Serial.begin(9600);
pinMode(LED_Red, OUTPUT);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), DoAction, CHANGE);
}
void DoAction()
{
SensorState = digitalRead(DOOR_SENSOR);
if (SensorState == HIGH) {
Serial.println("Opened");
blinkLED(10, 500);
}
else {
Serial.println("Closed");
}
}
void blinkLED(int repeats, int time)
{
for (int i = 0; i < repeats; i++) {
if (SensorState == HIGH) {
digitalWrite(LED_Red, HIGH);
delay(time);
digitalWrite(LED_Red, LOW);
delay(time);
}
else
return;
}
}
void loop()
{
}
You can't simply put a delay() on an interrupt's function. You need to just set a flag when the door is opened and based on that start blinkLED inside the main loop.
I also recommend you to use millis() function for an unblocking delay inside blinkLED function (e.g when you want to stop blinking while the door is closed).
const byte LED_Red = 13;
const byte DOOR_SENSOR = 2; // magnetic door sensor pin
// flag to check door is opened
volatile bool isOpened = false;
//flag to check already blinked
volatile bool isBlinked = false;
void setup()
{
Serial.begin(9600);
pinMode(LED_Red, OUTPUT);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), DoAction, CHANGE);
}
void DoAction()
{
if (digitalRead(DOOR_SENSOR) == HIGH)
{
//Serial.println("Opened");
isOpened = true;
}
else
{
isOpened = false;
isBlinked = false;
//Serial.println("Closed");
}
}
void blinkLED(int repeats, int time)
{
byte LEDState = LOW;
unsigned long delay_start = millis();
for (int i = 0; i < 2 * repeats; i++)
{
//Toggle LED state
if (LEDState == HIGH)
LEDState = LOW;
else
LEDState = HIGH;
// set value
digitalWrite(LED_Red, LEDState);
// some unblocking delay
while (millis() - delay_start < time)
{
// return if door is closed
if (!isOpened)
{
// turn off LED
digitalWrite(LED_Red, LOW);
return;
}
}
delay_start = millis();
}
isBlinked = true;
}
void loop()
{
// Check isBlinked beacue don't want to blink again until door is closed
if (isOpened && !isBlinked)
{
blinkLED(10, 500);
}
}

Resources