Arduino program that allows me to change state through comm port? - arduino

new here! been recommended many times to come here for help so here I am.
I'm supposed to write a program that allows me to change the rate of a blinking LED light through the comm port. I'm sure this is easy but I've honestly got no clue as I am behind in this class.
anything would help really, i honestly want to learn how to do this, not just come here and get the answer.
thanks in advanced!
// global variables
#include <EEPROM.h>
unsigned long ms_runtime;
int state;
// possible values 0 -> 1 -> 2 -> 3 -> 0
int one_ms_timer;
// define all timers as unsigned long (they are incremented every 100ms = 0.1s)
unsigned long timer1;
unsigned long button_dbnc_tmr = 0;
// timer1 is used for blinking LED
const int LED1 = 13;
// function prototypes
void read_memory(void);
void update_memory(void);
void comm_control(void);
void led_control(void);
void turnoff(void);
void flash_1s(void);
void flash_2s(void);
void flash_3s(void);
void timers(void);
void setup()
{
read_memory();
pinMode(LED1, OUTPUT);
Serial.begin(9600);
//initialize uart
}
void loop()
{
static bool allow_change;
static int counter;
timers();
comm_control();
led_control();
}
void led_control()
{
switch (state)
{
case 0:
turnoff();
break;
case 1:
flash_1s();
break;
case 2:
flash_2s();
break;
case 3:
flash_3s();
break;
}
}
void turnoff()
{
digitalWrite(LED1, LOW);
}
void flash_1s()
{
if (timer1 < 10)
digitalWrite(LED1, HIGH);
else
{
digitalWrite(LED1, LOW);
if (timer1 >= 20)
timer1 = 0;
}
}
void flash_2s()
{
if (timer1<20)
digitalWrite(LED1, HIGH);
else
{
digitalWrite(LED1, LOW);
if (timer1 >= 30)
timer1 = 0;
}
}
void flash_3s()
{
if (timer1<30)
digitalWrite(LED1, HIGH);
else
{
digitalWrite(LED1, LOW);
if (timer1 >= 40)
timer1 = 0;
}
}
void read_memory()
{
timer1 = EEPROM.read(one_ms_timer);
timer1++;
EEPROM.write(one_ms_timer, timer1);
Serial.begin(9600);
}
void update_memory()
{
EEPROM.update(timer1, one_ms_timer);
}
void comm_control(void);
{
char comm_reveier = serial_read;
if (
)
}
void timers(void)
{
if (millis() > (ms_runtime + 1))
{
ms_runtime = ms_runtime + 1;
one_ms_timer++;
}
else if (ms_runtime > millis())
ms_runtime = millis();
if (one_ms_timer > 99) //every 100 ms
{
one_ms_timer = 0;
button_dbnc_tmr++;
timer1++;
}
}

Load the Standard Firmata library on your Arduino board. Then use a library of your choice to build your comm prog. An overview of these can be found here.

Assuming you are using the Arduino IDE, this code sample should give you the general idea of what you need to do:
// pins for the LEDs:
const int ledPin = 13;
// Default blink rate
int rate = 1000;
void setup() {
// initialize serial:
Serial.begin(9600);
// make the pins outputs:
pinMode(ledPin, OUTPUT);
}
void loop() {
// if there's any serial available, read it:
while (Serial.available() > 0) {
// look for the next valid integer in the incoming serial stream:
int rate = Serial.parseInt();
}
digitalWrite(ledPin, HIGH); // turn the LED on (HIGH is the voltage level)
delay(rate); // wait for a second
digitalWrite(ledPin, LOW); // turn the LED off by making the voltage LOW
delay(rate); // wait for a second
}

Related

What does this error mean, This is using the IR Remote library and the ATTINY85

I am attempting to upload my code to the ATTiny85, but whenever I do, I get this error.
Here is the error:
error: ISO C++ forbids declaration of 'str' with no type [-fpermissive]
void sendPronto(const __FlashStringHelper *str, unsigned int times = 1U);
Here is the code:
#include <IRremote.h>
int IRpin = 1;
IRrecv IR(IRpin);
//Motor 1 (Right) Backward Pin
const byte MOTOR1_BWD = 2;
//Motor 1 (Right) Forward Pin
const byte MOTOR1_FWD = 3;
decode_results cmd;
int speedpin = 5;
const byte spd = 255;
void stop() {
digitalWrite(MOTOR1_BWD, LOW);
digitalWrite(MOTOR1_FWD, LOW);
}
void back() {
digitalWrite(MOTOR1_BWD, HIGH);
digitalWrite(MOTOR1_FWD, LOW);
analogWrite(speedpin, spd);
}
void forward() {
digitalWrite(MOTOR1_BWD, LOW);
digitalWrite(MOTOR1_FWD, HIGH);
analogWrite(speedpin, spd);
}
void setup() {
IR.enableIRIn();
pinMode(MOTOR1_BWD, OUTPUT);
pinMode(MOTOR1_FWD, OUTPUT);
digitalWrite(MOTOR1_BWD, LOW);
digitalWrite(MOTOR1_FWD, LOW);
stop();
}
void loop() {
IR.resume();
if (cmd.value == 0xFF906F) {
forward();
}
if (cmd.value == 0xFFA25D) {
stop();
}
if (cmd.value == 0xFFE01F) {
back();
}
}
I copy pasted your code and it compiled just fine for the ATTiny85. Try redownloading that library using the library manager in the IDE

Implementing the function interrupt with if statements

I want to implement the function interrupt () but I don't know exactly how..In this case there is 2 for loops which can be seen in the code:I want whenever one of the 2 buttons is pressed the process inside the loop to be interrupted immediately:
void loop() {
int brightButton = digitalRead(K1);
int ldrStatus = analogRead(ldrPin);
if (brightButton == LOW && ldrStatus >= 200)
{
for (int i = 0; i < 10; i++)
{
digitalWrite(greenLed, HIGH);
tone(buzzer,400);
delay(500);
noTone(buzzer);
delay(500);
}
}
else {
digitalWrite(greenLed, LOW);
}
int tempButton = digitalRead(K2);
int valNTC = analogRead(NTC);
if (tempButton == LOW && valNTC > 512)
{
for (int i = 0; i <10; i++)
{
digitalWrite(redLed, HIGH);
tone(buzzer,450);
delay(300);
noTone(buzzer);
delay(1000);
}
}
else {
digitalWrite(redLed, LOW);
}
}
Example code from the Arduino manual:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
Note that this will interrupt the for loop and return to it once the interrupt service routine is finished.
If you want to abort the for loop check the pin state in every loop cycle and break if you want to leave the for loop or return if you want to leave loop().
Of course this is not "immediately".

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);
}
}

Toggle pin on Arduino Micro without disrupting operation

I have a code that once it receives a particular input over the serial it will turn 2 pins high, and wait for an interrupt to occur and run its code. I tried using an infinite loop(while 1) but the interrupt routine can't get executed when the button is pressed.
I want the outputs LED and BEEP to toggle after 'C' is received and until the interrupt occurs.
// Declarations before
void loop() {
while(Serial.available())
{
char data = Serial.read();
if(data == 'C')
{
digitalWrite(BEEP, 1);
digitalWrite(LED, 1);
flag = true;
}
}
// Interrupt routine
When this code receives a 'C' char from the serial the code starts a led flashing for 50 msec on and for 50 msec off, the led flashing stops when the interrupt ITR_PIN is generated (the ISR buttonPressed function will be called!)
#define ITR_PIN 3
volatile bool start = false;
bool ledstatus = false;
int LED= 4;
/**
* This method is called on the interruption raised on the falling front of the PIN2
* The start flag is used to avoid rebound front. Interruptions are disabled inside the
* interrupt vector method.
* start is reset once it has been processed in the main loop()
*/
void buttonPressed()
{
start=false;
}
void setup()
{
cli();
pinMode(ITR_PIN, INPUT);
pinMode(LED, OUTPUT);
attachInterrupt(0, buttonPressed, FALLING); // Pin 3
sei();
Serial.begin(9600);
}
void loop(){
while(Serial.available())
{
char data = Serial.read();
if(data == 'C')
{
start = true;
}
}
if (start)
{
ledstatus=!ledstatus;
digitalWrite(LED, (ledstatus)?HIGH:LOW);
delay(50);
} else {
if (ledstatus) {
ledstatus=false;
digitalWrite(LED,LOW);
}
}
}
I just tried this on a simulator:
#define ITR_PIN 3
volatile boolean start = false;
volatile boolean flag = false;
int LED= 4;
/**
* This method is called on the interruption raised on the falling front of the PIN2
* The start flag is used to avoid rebound front. Interruptions are disabled inside the
* interrupt vector method.
* start is reset once it has been processed in the main loop()
*/
void buttonPressed()
{
if(flag)
{
if (!start)
{
start = true;
}
}
}
void setup()
{
cli();
pinMode(ITR_PIN, INPUT);
pinMode(LED, OUTPUT);
attachInterrupt(0, buttonPressed, FALLING); // Pin 3
sei();
Serial.begin(9600);
}
void loop(){
while(Serial.available())
{
char data = Serial.read();
if(data == 'C')
{
digitalWrite(LED, 1);
flag = true;
}
}
if(flag == true)
if (start)
{
digitalWrite(LED, LOW);
delay(50);
start = false;
flag=false;
}
}
(it's just a reduced version of yours, I just removed the stepper dependancies and marked flag as volatile). It works with this hardware:
However, I'm pretty sure that you haven't added the pullup to your circuit!
The solution is:
add a resistor (e.g. 10 kOhm) between pin 3 and +5V
enable the internal pullup
Solution 2 is the preferred one: you just have to change
pinMode(ITR_PIN, INPUT);
into
pinMode(ITR_PIN, INPUT_PULLUP);
EDIT:
According to your comment I think that the behavior should be different:
Everything is off
When you receive a C on the serial interface the led starts "blinking"
When the interrupt is asserted it stops blinking.
I modified the code to achieve this; I slightly reduced the rest of the code (but you can merge it with the previous one)
#define ITR_PIN 3
volatile boolean flag = false;
const int blink_period_ms = 500; // Blink period in milliseconds
unsigned long initialBlinkTime;
int LED= 4;
void buttonPressed()
{
flag = false;
}
void setup()
{
cli();
pinMode(ITR_PIN, INPUT);
pinMode(LED, OUTPUT);
attachInterrupt(0, buttonPressed, FALLING); // Pin 3
sei();
Serial.begin(9600);
}
void loop(){
while(Serial.available())
{
char data = Serial.read();
if(data == 'C')
{
if (!flag)
{
initialBlinkTime = millis();
flag = true;
}
}
}
if(flag)
{
int currentTime = millis() - initialBlinkTime;
while (currentTime > blink_period_ms) currentTime -= blink_period_ms;
digitalWrite(LED, currentTime < blink_period_ms/2);
// Insert here the other instructions
delay(50);
}
}

Arduino simple button activated light

I keep getting an error when I run this code any solutions?
{
pinMode(button2pin, INPUT, 3);
button1State= digitalRead(button1Pin 2);
}
if (button1State == LOW)
{
}
This code presumes that you have connected one side of your switch to digital pin 3 and the other side to ground and that your button is normally open.
const int button2pin = 3;
int button2State = 0;
void setup(){
pinMode(button2pin, INPUT_PULLUP);
Serial.begin(9600); // for debug only
}
void loop(){
button2State = digitalRead(button2pin);
if(button2State == LOW){
Serial.print("Button 2 pressed"); // for debug only
}
}
This project turns on the light when the button is pressed. Maybe can help you with your problem.
int buttonPin = 2;
int ledPin = 5;
//This var read the state of Buttonpin
int buttonState = 0;
void setup() {
// set the pin as output
pinMode(ledPin , OUTPUT);
// set the pin as input
pinMode(buttonPin , INPUT);
}
void loop(){
// read the button state
buttonState = digitalRead(buttonPin );
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}

Resources