PWM fadeing LED on arduino - c

I`m trying to blink led with PWM on Arduino, and I dont know whats wrong. But my LED is not fadeing. What is wrong? I think that I have bad registers settings, but Im not sure. Led is connected on arduino pin 11. Thank you.
#include <avr/io.h>
#include <util/delay.h>
const int delay=1000;
void initialize_PWM()
{
TCCR0A|=(1<<WGM00)|(1<<WGM01)|(1<<COM0A1);
TCCR0B=1;
DDRB|=(1<<PB3);
}
void set_pwm(uint8_t data)
{
OCR0A=data;
}
int main (void)
{
initialize_PWM();
uint8_t brightness=200;
while(1)
{
for(brightness=0;brightness<255;brightness++)
{
set_pwm(brightness);
_delay_ms(1);
}
for(brightness=255;brightness>0;brightness--)
{
set_pwm(brightness);
_delay_ms(1);
}
}
return 0;
}

Have you looked at the 'Fade' example program?
/*
Fade
This example shows how to fade an LED on pin 9
using the analogWrite() function.
This example code is in the public domain.
*/
int led = 9; // the pin that the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of pin 9:
analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
See http://arduino.cc/en/Tutorial/Fade

Your code seems correct, but you are using timer0, that can generate pwm on Arduino UNO's pin 5 and 6, as shown in the datasheet. So you should set the ddrd bit 6 with a
DDRD |= (1 << PD6)
, that is pin 6 on Arduino, not pin 11. If you want pwm on pin 11 you should use timer2 instead.

Related

Wake up Adafruit Feather 32u4 from sleep mode with external interrupt

I have an Adafruit Feather ATMega 32u4. I want to put it into sleep mode and wake it up with pressing a switch as an external interrupt. This is what I tried so far and which worked:
switching a LED on and off with the switch
putting the Adafruit to sleep and let it wake up with a watchdog timer.
I tried to combine the code examples that I found in the Internet to make the code fit my board. I manage to put it to sleep but then I have to reset it because the Interrupt doesn't work. I would be very happy for any help and please don't blame me, I am a complete beginner!
Here is my code:
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
int pin2 = 2;
void pin2Interrupt(void) {
/* This will bring us back from sleep. */
detachInterrupt(digitalPinToInterrupt(2));
}
void enterSleep(void) {
/* Setup pin2 as an interrupt and attach handler. */
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(digitalPinToInterrupt(2), pin2Interrupt, RISING);
if (digitalRead(pin2)){
sleep_mode();
}
/* The program will continue from here
* First thing to do is disable sleep.
*/
sleep_disable();
}
void setup() {
Serial.begin(9600);
/* Setup the pin direction. */
pinMode(pin2, INPUT_PULLUP);
Serial.println("Initialisation complete.");
}
int seconds = 0;
void loop() {
delay(1000);
seconds++;
Serial.print("Awake for ");
Serial.print(seconds, DEC);
Serial.println(" second");
if(seconds == 3){
Serial.println("Entering sleep");
delay(200);
seconds = 0;
enterSleep();
}
}
Update:
#include "LowPower.h"
#include "avr/interrupt.h"
#define BUTTON 3
#define LEDPIN 13
void wakeUp() {
detachInterrupt(digitalPinToInterrupt(BUTTON));
}
void Blink(byte ledPin, int msDelay, byte loops) {
for (byte i=0; i<loops; i++) {
digitalWrite(ledPin, LOW);
delay(msDelay);
digitalWrite(ledPin, LOW);
delay(msDelay);
}
}
void setup() {
pinMode(BUTTON, INPUT);
digitalWrite(BUTTON, LOW);
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW);
}
void loop() {
cli();
EIMSK &= ~(1 << INT0);
EICRA |= (1 << ISC01) | (1 << ISC00);
EIMSK |= (1 << INT0);
attachInterrupt(digitalPinToInterrupt(BUTTON), wakeUp, CHANGE);
sei();
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
Blink(LEDPIN, 100, 3);
Serial.println("AWAKE!");
delay(100);
}

What is wrong with this code for glowing LEDs using IR sensor for AVR?

/*This code takes in inputs from IR sensors connected on PA0 and PA1
and glows LEDs connected on PB0 and PB1*/
#include <avr/io.h>
int main()
{
DDRA=0x00; // PORTA (PA0 and PA1) will act as input
DDRB=0x03; //The last two pins PBO and PB1 will act as output.
int x=0x03 & PINA; //Initially when PINA=0, x=0
if (x==0x00)
{
PORTB=0x00;
}
else if (x==0x01)
// If input is given to PA0 then PINA=0x01 and x=0x01
{
PORTB=0x01;
}
else if (x==0x02)
// If input is given to PA1 then PINA=0x02 and x=0x02
{
PORTB=0x02;
}
else if(x==0x03)
// If input is given to PA0 and PA1 then PINA=0x03 and x=0x03
{
PORTB=0x03;
}
return 0;
}
A solution to have a program that runs continuously is that below. This solution contains some logic adjustments to your code. The logic adjustments allow the code to don't modify all the bits of the port B, in this way the code modifies only the bits 0 and 1 of the port. That allows to use the other bits for other purposes.
#include <avr/io.h>
void main()
{
DDRA=0x00; // PORTA (PA0 and PA1) will act as input
DDRB=0x03; //The last two pins PBO and PB1 will act as output.
int x;
PORTB=0;
PORTA=0;
for( ;; ) {
x=0x03 & PINA; //Initially when PINA=0, x=0
if (x==0x00)
{
PORTB&=(~3);
}
else if (x==0x01)
// If input is given to PA0 then PINA=0x01 and x=0x01
{
PORTB&=(~2);
PORTB|=0x01;
}
else if (x==0x02)
// If input is given to PA1 then PINA=0x02 and x=0x02
{
PORTB&=(~1);
PORTB|=0x02;
}
else`enter code here` if(x==0x03)
// If input is given to PA0 and PA1 then PINA=0x03 and x=0x03
{
PORTB|=0x03;
}
// Here you may insert a delay
//delay(50);
}
}
I think a good solution might be the following code:
#include <avr/io.h>
void main()
{
DDRA=0x00; // PORTA (PA0 and PA1) will act as input
DDRB=0x03; //The last two pins PBO and PB1 will act as output.
PORTB=0;
PORTA=0;
for( ;; ) {
PORTB &=(~3);
PORTB |= (PORTA & 3);
// Here you may insert a delay
// delay(50);
}
}

MSP430 Function Call Being Skipped

I am programming an MSP430 microcontroller with the MSP430 LaunchPad Dev Kit and I am running into some problems on this simple code.
#include <msp430.h>
void Delay(void);
#define LED1 BIT0 //define LED1 as bit 0 (0x00)
#define LED2 BIT6 //define LED2 as bit 6 (0x40)
#define delayTime 20000 //define iTime as 20000
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; //stop watchdog timer
P1DIR |= (LED1|LED2); //set P1.0 and P1.6 to output direction (P1.3 is naturally an input)
P1OUT |= LED1; //set P1.0 high so the LEDs will blink alternatively
while(1)
{
Delay();
P1OUT ^= (LED1|LED2); //toggle P1.0 using exclusive-OR
}
}
void Delay(void)
{
int i = 0;
while(delayTime > i)
{
i++;
}
}
This code compiles fine, but when debugging the code, the function call 'Delay()' is skipped entirely and the function is never entered. However, when I give the function a return type of 'unsigned int' like this:
unsigned int Delay(void)
{
int i = 0;
while(delayTime > i)
{
i++;
}
return 1;
}
I can call the Delay function in an if statement like the one below and the debugger will enter the function.
if(Delay() == 1)
{
P1OUT ^= (LED1|LED2); //toggle P1.0 using exclusive-OR
}
I'm sure there is some simple oversight that I'm making. I can't for the life of me figure out why the debugger is skipping my first void function call. Any wisdom?
swineone has responded with the following correct solution in a comment:
"Try changing the declaration int i = 0; to volatile int i = 0; in the
Delay() function. This tells the optimizer not to touch that variable,
and may be the difference between the optimizer optimizing the code
away or not."
Thanks for the help!
It's recommended to work with interrupts. Such a task goes to this:
#include "io430.h"
#define ON 1
#define OFF 0
#define LED1 P1OUT_bit.P0
#define LED2 P1OUT_bit.P6
void init(void)
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1OUT = 0x00;
P1DIR = 0xFF;
// initialize Timer0_A
TA0CCR0 = 62500; // set up terminal count
TA0CTL = TASSEL_2 + ID_3 + MC_1; // configure and start timer
// enable interrupts
TA0CCTL0_bit.CCIE = 1; // enable timer interrupts
__enable_interrupt(); // set GIE in SR
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{
LED1 = ~LED1;
}

Can only read once from PIC16's RCO port

Been searching for an answer for this for a few days now. I'm trying to create this simple verification program where if I push a button it drives the voltage on RC0 to 5 volts, and when the button is unpushed, a pulldown resistor pulls the pin down to 0. The problem is, the code will only work the first time I push the button. After that it will not enter the if (RC0 == 1) loop. Here is my code snippet. What am I missing here?
void main(void){
/* Configure the oscillator for the device */
ConfigureOscillator();
/* Initialize I/O and Peripherals for application */
InitApp();
TRISB = 0x0F; // turn on RB7 for use as output
TRISC = 0xFF; // turn on RC0 for use as input
ANSEL = 0b11101111; // use RC0 as digital input
unsigned char time = 0;
while (1) {
//delay for 10 seconds
if (PORTCbits.RC0 == 1) {
while (time < 10) {
/* TODO */
RB7 = 1;
__delay_ms(100);
RB7 = 0;
__delay_ms(100);
time++;
}
}
if (PORTCbits.RC0 == 0){ //This if statement will always execute when
//RC0 == 0, but will not execute when I push
//the button. This really confuses me.
//Can RCO be given a value different than 1?
__delay_ms(2000);
}
RB7 = 0;
__delay_ms(500);
RB7 = 1;
__delay_ms(500);
}
}

Need help with timer

For last 2 weeks am trying to learn timer & interrupt & wrote a program (with my understanding) to blink LEDs on ATMEGA2560 but no matter what I do TCNT0 never increments & ISR() function never gets called. Where am I going wrong and how can I fix it? Here is my code:
#include<avr/io.h>
#include<avr/interrupt.h>
#define READ_ATMEGA(ADDR) *((P_CHAR)(BASE_ADDR + ((ADDR) * ADDR_MULTIPLIER)))
#define WRITE_ATMEGA(ADDR, DATA) *((P_CHAR)(BASE_ADDR + ((ADDR) * ADDR_MULTIPLIER))) = DATA
#define BASE_ADDR 0x20
void init_timer0_ovf_interrupt(void);
void timer0_interrupt_isr(void);
void initialize_ports(void);
void delay(unsigned int no_65_5ms_interrupts);
void __attribute__((ISR)) timer0_interrupt_isr(void);
//#pragma interrupt_handler timer0_interrupt_isr:24
unsigned int delay_timer;
int main(void)
{
initialize_ports();
init_timer0_ovf_interrupt();
delay(46);
return 0;
}
void initialize_ports(void)
{
READ_ATMEGA(4) = 0xff;
WRITE_ATMEGA(5, 0x00);
}
void delay(unsigned int no_65_5ms_interrupts)
{
TCNT0 = 0x00;
delay_timer = 0;
while(delay_timer <= no_65_5ms_interrupts)
{
;
}
}
void init_timer0_ovf_interrupt(void)
{
TCCR0A = 0X00;
TCCR0B = 0x02;
TIMSK0 = 0x01;
TIFR0 = 1<<0;
OCR0A = 25;
sei();
}
void timer0_interrupt_isr(void)
{
delay_timer++;
if(delay_timer >= OCR0A)
{
PORTB = ~(PORTB);
delay_timer = 0;
}
}
The global variable delay_timer is shared between interrupt and non-interrupt code. It should be declared as volatile as the value can change outside of delay().
If you look at the generated code for delay() you'll probably see that the value of delay_timer isn't being re-read while spinning in the while loop.
Also, volatile isn't enough. You've got non-interrupt code and interrupt code both writing to the same variable (delay_timer). You need to protect writes to the variable in non-interrupt code, there's a race-condition there. The easy/lazy way is to disable interrupts & restore them in the non-interrupt code.
(As for setting up your interrupts & starting your timer, that info should be in the chip's datasheet. Usually that's the part that's easier to get right, it's the shared data stuff that bites people.)
3-4 days ago, I wrote the same program a little differently & got LEDs blinking but still not sure whether it is the correct way of using timer & interrupt. Could anyone please see this & tell me whether it's the correct or not? I managed to write this program by reading programs of timers, interrupts.
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t intrs;
ISR(TIMER0_OVF_vect) {
/* this ISR is called when TIMER0 overflows */
intrs++;
/* strobe PORTB.5 - the LED on arduino boards */
if (intrs >= 61){
PORTB = ~PORTB;
intrs = 0;
}
}
int main(void) {
TCCR0B = 0x02;
/* Enable Timer Overflow Interrupts */
TIMSK0 = 0x01;
/* other set up */
DDRB = 0xff;
TCNT0 = 0;
intrs = 0;
/* Enable Interrupts */
sei();
while (1)
; /* empty loop */
}
If it's the correct way then I can start working on next step.
Thanks
If could be that your while loop in the delay function doesn't do anything and will not increment delay_timer so you are stuck in an endless loop:
void delay(unsigned int no_65_5ms_interrupts)
{
TCNT0 = 0x00;
delay_timer = 0;
while(delay_timer <= no_65_5ms_interrupts)
{
; //Nothing is happening here!!
}
}

Resources