Making a program where LEDS are individually turned on and off according to the sequence - c

I am writing a program where I have to turn the LEDS on and off according to the following sequence, (delay of half a second between each state):
State 1- Led 1 ON Led 2 ON Led 3 OFF
State 2- Led 1 OFF Led 2 ON Led 3 ON
State 3- Led 1 ON Led 2 OFF Led 3 OFN
The LEDs are located on the OLED1 Xplained extension of the ATmega324PB Microcontroller, and I am using the IAR Embedded Workbench. This is the code I've written so far:
#include "iom324pb.h"
#include <ioavr.h>
#include <intrinsics.h>
void led3_on()
{
DDRA_DDRA3=1;
PINA_PINA3=1;
}
void led3_off()
{
DDRA_DDRA3=0;
}
void led2_on()
{
DDRD_DDRD4=1;
PIND_PIND4=1;
}
void led2_off()
{
DDRD_DDRD4=0;
}
void led1_on()
{
DDRD_DDRD5=1;
PIND_PIND5=1;
}
void led1_off()
{
DDRD_DDRD5=0;
}
void state1()
{
led3_off();
led2_on();
led1_on();
}
void state2()
{
led3_on();
led1_off();
}
void state3()
{
led2_off();
}
void main (void)
{
while(1)
{
state1();
__delay_cycles(8000000);
state2();
__delay_cycles(8000000);
state3();
__delay_cycles(8000000);
}
}
I have managed to do the first 2 states but I have trouble with the last one. Basically for some reason I don't understand if I try to turn LED1 back on it would mess up the whole sequence.

state3() is missing a led1_on();
There is little reason to only adjust 2 LEDs per state. Turn off/on all 3 in each stateN().
There is also little reason to only adjust 1 register when turning the LED on/off. Set both the pin and the DDR in each ledN_...(). funciton.

Related

How can I run two loops at the same time?

I have written code that makes LEDs blinks and moves a servo to several different directions. Here's the basic structure:
while(true){
//led on
//wait
//led off
//wait
}
while(true){
//servo to 45
//servo to 90
//servo to 270
}
I want both to run at the same time. The code above only turns on the LEDs, and infinitely since it's in the loop. The servo never works. I looked at other questions on here but I couldn't find anything relevant.
How can I make both the LEDs and servo work at the same time?
In general you cannot use two infinite loops. That's because it is senquentional program, so it cannot run second when until the first one is done. So if first loop is infinite, the second will never run.
To do some kind of 'multithreading', in simplest way is to use timers and interrupts.
In your case you want to run two different task. Blinking led and steering servos. When you use wait()/sleep()/delay(), the uC is simply stopping (except handling other things like interupts etc.). So you can set timers and in the interrupt blink led. Or better in the interrupt just set some flag, and in your main just check if flag has changed. Than just handle blink. So in general you will have in you main sth like this:
volatile uint8_t nowBlink = 0
ISR(TIMER1_OVF_vect)
{
// some timer handling and then:
nowBlink = 1
}
loop(){
if(nowBlink){
toggleLed();
nowBlink = 0;
}
setServo(123123);
}
Setting intterupt to 1 s, will blink your led with freq of 1 Hz, and then other parts of program will be done.
Here you have timers explained, and Here you have some libraries. Just read that and you should be master of arduino.
Best regards, voodoo16.
Don't use functions like delay_ms(), wait () etc. Try interrupt.
Use the struture like this :
int flag = 0;
void func_delay_50ms () interrupt
{
// set initial condition
flag ++;
}
void main
{
while (1)
{
if (flag == 4) // per 200ms
{
led = -led;
flag = 0;
}
if (!(flag % 2)) // per 100ms
{
servo ();
}
}
}
note : servo () should not block for a long time.
There are no really conturrent threads, And you should create an illusion to realize it.
(:з」∠) My poor English. pardon me.
Blinking a LED does not really require code on the MCU. You can use a timer and a PWM signal. https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM
I wrote an Operating System for Arduino which supports multithreading in order to run multiple loops at once. Note that the servo has a range from 0-180. You can't turn in 270 degrees. You can find the source and further documentation here https://github.com/DrBubble/ArduinoOS.
This example code should do exactly what you want when running under the ArduinoOS.
#include "KernelInitializer.h"
#include "Servo.h"
#include "Led.h"
void setup()
{
KernelInitializer::InitializeKernel(mainThread);
}
void mainThread()
{
InitTask(secondThread);
while (true)
{
Led led(2); // replace 2 with the pin of your led
while (true)
{
led.TurnOn();
sleep(1000);
led.TurnOff();
sleep(1000);
}
}
}
void secondThread()
{
Servo servo(9); // replace 9 with the pin of your servo
while (true)
{
servo.SetValue(45);
sleep(1000);
servo.SetValue(90);
sleep(1000);
servo.SetValue(180);
sleep(1000);
}
}
You can simply use a goto statement
in both the loop.....you dont even need a loop if you use goto, like in assembly language.
c code for it is:
#include<stdio.h>
int main()
{
int count;
loop1:for(;;)
{
printf("Loop 1\n");
goto loop2;
}
loop2:for(;;)
{
printf("Loop 2\n");
goto loop1;
}
return 0;
}

window Watchdog Timer STM32F4

Edited
DONE NOW .. I'll reconstruct the code, but now it's done and tested
I need to implement a timer that checks for conditions every x sec .. the problem I face that the program doesn't reset when it enters infinite loop ( away for check like if the system has been halted) ...
these links helped me .. manual from page 74 http://www2.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf ..
and this link http://www.programmershare.com/3518407/
thanks in advance
I currently have this code :
#include "stm32f4xx.h"
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_wwdg.h>
void setup_Periph(void);
void Delay(unsigned long ms);
void Delay(unsigned long ms)
{ unsigned long i,j;
for(i=0;i<ms;i++)
for(j=0;j<1450;j++);
}
void setup_Periph(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
//port initialization
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_Init(GPIOD,&GPIO_InitStructure);
}
void ResetWatchdog(void)
{ WWDG_SetCounter(80);}
void WWDG_IRQHandler(void)
{
if (WWDG_GetFlagStatus())
{
WWDG_SetCounter(0x7f);
WWDG_ClearFlag();
}
}
void FeedDog(float round)
{
while(round)
{ Delay (65);
WWDG_SetCounter(127);
round--;}
}
int main(void)
{
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
//System Clock auf Watchdog
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
WWDG_SetPrescaler(WWDG_Prescaler_8);
//WWDG clock counter = (PCLK1(30MHz)/4096)/1 = 7324 Hz (~137 us)
WWDG_SetCounter(80); //Werte 0x40 und 0x7F
WWDG_SetWindowValue(80); //0x80
//Reset < 120 > 64
WWDG_Enable(127); //WWDG timeout = ~137 us * (127-64) = 8.6ms
WWDG_ClearFlag();
WWDG_EnableIT();
setup_Periph();
//make sure the clk is stable
RCC_HSEConfig(RCC_HSE_ON);
while(!RCC_WaitForHSEStartUp());
GPIO_SetBits(GPIOD, GPIO_Pin_1);
Delay(10000); //10 ms
GPIO_ResetBits(GPIOD, GPIO_Pin_1);
Delay(10000); //100 ms
while (1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_0);
Delay(10000); //10 ms
GPIO_ResetBits(GPIOD, GPIO_Pin_0);
Delay(10000); //100 ms
void ResetWatchdog(void);
WWDG_SetCounter(80);
FeedDog(8);
for(;;) {}
}
}
There are several things very obviously wrong here. Most troubling among them are:
Your Delayms() function does not implement any kind of delay. It appears to configure one of the LEDs to flash.
You are never calling InitWatchdog(). (Instead, you are declaring its prototype within main() for some reason.)
I don't want this to sound too harsh, but: do you know C? This code reads as though it's been put together by copying and pasting pieces from examples without understanding them. If you do not know C, attempting to develop software for an embedded system is not an effective way to learn it, especially without guidance.

The program for LEDs 8x8 doesn't function in Arduino Uno. I'm not using the pinMode() method. I'm using the other method for specification

The program for LEDs 8x8 doesn't function in Arduino Uno. I'm not using the pinMode() method to specify pin OUTPUT for LEDs. I'm using the method "LedControl"
The specification pin:
"lc=LedControl(4,6,5,1);"
for setting the pin. Why ?
This program compiles and executes without problems.
I'm importing the library correctly.
I'm using this example:
#include "LedControl.h"
/*Now we need a LedControl to work with.
pin 4 is connected to the DataIn
pin 5 is connected to the CLK
pin 6 is connected to LOAD / CS
We only have a single MAX7219 */
LedControl lc=LedControl(4,6,5,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=500;
void setup() {
/* The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call */
lc.shutdown(0,false);
lc.setIntensity(0,8);
lc.clearDisplay(0);
}
void loop() {
lc.setIntensity(0,8);
single();
lc.clearDisplay(0);
}
/* This function will light up every Led on the matrix. The led will blink along with the row-number. row number 4 (index==3) will blink 4 times etc. */
void single() {
for(int row=0;row<8;row++) {
for(int col=0;col<8;col++) {
delay(50);
lc.setLed(0,row,col,true);
delay(50);
for(int i=0;i<col;i++) {
lc.setLed(0,row,col,false);
delay(50);
lc.setLed(0,row,col,true);
delay(50);
}
}
}
}
The LedControl library uses pinMode in the background to make the LEDs easier to control. When you give values to LedControl, it automatically uses pinMode, which operates as pinMode(pin, OUTPUT|INPUT).

how to interrupt arduino when data recieved via rx pin

what am I doing wrong ? I have the RX of the Bluetooth HC-07 wired into pin2 looking for a change in voltage when data is received to start a interrupt.
I'm trying to cause an interrupt when data is received via the Bluetooth.
#include <SoftwareSerial.h>// import the serial library
#include <PinChangeInt.h>
SoftwareSerial Genotronex(10, 11); // RX, TX
int ledpin=13; // led on D13 will show blink on / off
int BluetoothData; // the data given from Computer
void doSomething(void);
void setup() {
// wil run once
Genotronex.begin(9600);// data rate for comunicating
Genotronex.println("Bluetooth On please press 1 or 0 blink LED ..");
pinMode(ledpin,OUTPUT);
interrupts();
pinMode(2,INPUT);
attachInterrupt(0,doSomething, CHANGE);
}
void loop() {
// Main body of code
}
void doSomething(){
Genotronex.println("INTERRUPT!!!!!!!!!!!!");
digitalWrite(ledpin,1);
delay(1000);
digitalWrite(ledpin,0);
delay(1000);
detachInterrupt(0);
}
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
This is a repost of the code ,, I've taken out what the comments said and added what you recommended,, for the most part. The code runs but change state never changes back it only changes once? I've tried taking out DetachInterrupt but the actual interrupt stops working then ? Any more ideas? Thanks for the help btw
#include <SoftwareSerial.h>// import the serial library
SoftwareSerial Genotronex(10, 11); // RX, TX
int ledpin=13; // led on D13 will show blink on / off
int BluetoothData; // the data given from Computer
void doSomething(void);
volatile int state = LOW;
void setup() {
// wil run once
Genotronex.begin(9600);// data rate for comunicating
Genotronex.println("Bluetooth On please press 1 or 0 blink LED ..");
pinMode(ledpin,OUTPUT);
pinMode(2,INPUT);
attachInterrupt(0,doSomething, CHANGE);
}
void loop() {
// Main body of code
digitalWrite(ledpin, state);
}
void doSomething(){
Genotronex.println("INTERRUPT!!!!!!!!!!!!");
state = !state;
detachInterrupt(0);
}
delete:
detachInterrupt(0);
If you can change interrupt from CHANGE to HIGH/LOW and add something like 'debouncing'. My version here (HIGH state interrupts):
void interruptfunction() {
//your interrupt code here
while(1){
if (digitalRead(2)==LOW){
delay(50);
if (digitalRead(2)==LOW) break;
}
}
}
Or this: (not tested)
void interruptfunction() {
//your interrupt code here
if (digitalRead(2)==HIGH) state=true;
else state=false;
while(1){
if (digitalRead(2)!=state){
delay(50);
if (digitalRead(2)!=state) break;
}
}
}
If you have to react on CHANGE try leaving detachInterrupt(0); but reattach it somewhere in your main loop.

How can I create interrupts in C for Arduino?

So I did this code for Arduino in C. It is for controlling a stepper motor. But every time I have to wait until the microcontroller begins a new loop so that it can take the value for the new variables, how can I create an interrupt so it will do it in any time of the program?
#include <avr/io.h>
#define F_CPU 4000000UL
#include <util/delay.h>
#include "IO/ioconfig.h"
#include "leebotones/leebotonesA.h"
#include "leebotones/leebotonesB.h"
#include "rutina/avanza.h"
#include "rutina/retrocede.h"
char variableA = 0;
char variableB = 0;
int main(void){
ioconfig();
while(1) {
if (leebotonesA()==1) {
variableA++;
} //Fin de if leebotonesA.
if (leebotonesB()==1) {
if (variableA==0) {
variableB=1;
}
else {
variableB=0;
}
}
if (variableA==2) {
variableA=0;
PORTD=0x00;
_delay_ms(10000);
} //Fin de if variableA.
if (variableA==1 && variableB==0) {
avanza();
} //Fin de if leebotonesA.
if (variableA==1 && variableB==1) {
retrocede();
}
_delay_ms(25);
}//End of while
}// End of main
A hardware interrupt on the Arduino occurs when one of the interrupt pins receives a change of state. The function to use, if you have access to the Arduino library, is attachInterrupt.
Example code to listen for an interrupt (derived from the documentation I linked to, I added comments to help explain):
// The Arduino has an LED configured at pin 13
int pin = 13;
// Holds the current state of the LED to handle toggling
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
// First Parameter:
// 0 references the interrupt number. On the Duemilanove, interrupt 0
// corresponds to digital pin 2 and interrupt 1 corresponds to digital pin
// 3. There are only two interrupt pins for the Duemilanove and I believe
// the Uno too.
// Second Parameter:
// blink is the name of the function to call when an interrupt is detected
// Third Parameter:
// CHANGE is the event that occurs on that pin. CHANGE implies the pin
// changed values. There is also LOW, RISING, and FALLING.
attachInterrupt(0, blink, CHANGE);
}
void loop()
{
// Turns the LED on or off depending on the state
digitalWrite(pin, state);
}
void blink()
{
// Toggles the state
state = !state;
}
There is also a concept of Pin Change Interrupts that is supported on every pin. See the bottom part of introduction to interrupts for more info.
However, sometimes a hardware interrupt can be avoided by refactoring your code. For example, keep your loop() running quickly --- mostly just reading inputs, limit the use of delay() --- and in the loop, call a function when the targeted inputted value is detected.
MSTimer2 is an Arduino library function to let you set timer interrupts.
Another alternative to delay, rather than interrupts, is to set a timer and check it each time through the loop. http://arduino.cc/en/Tutorial/BlinkWithoutDelay explains the concepts. The Metro library http://arduino.cc/playground/Code/Metro implements this and is easy to use. I've used it instead of delay() so that I can check for a button push while my robot is moving.

Resources