USART won't allow inputs to work

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I came familiar with the USART communication type a little less than a month ago I was trying to practice so that I can learn Usart communications of the Avr (Atmega8) and a Bluetooth Module (Hc-05). Everything went well I was able to control some leds(4 to be exact) with the mobile phone wirelessly. I though the setup would be great for my bedroom lighting control so I tried to install some buttons as inputs so that I can control the relays from my Phone (via bluetooth ) and well as the buttons I am trying to install.

 

But the problem I am facing is that either the button code works or the bluetooth one if I try to merge them into a single project then the Avr responds only to the bluetooth commands and not to the button inputs . Is there anything that I need to know so that I can correct the code.

Any help would be greatly appreciated as I am struck at this for over 2 days didn't found something relevant on the internet.

Using Atmega8 clocked at 8MHz internal clock and some buttons and Hc-05 bluetooth module.

 

Here is the code that I have written, and please overlook the fact that it's a bit primitive in nature


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "debounce.h"
#include "USART_RS232_H_file.h"		/* include USART library */
void flasher (void);

void flasher ()
{
	PORTB |= (1<<PB3);
	_delay_ms(100);
	PORTB |= (1<<PB4);
	PORTB &= ~(1<<PB3);
	_delay_ms(100);
	PORTB &= ~(1<<PB3);
	PORTB &= ~(1<<PB4);
	_delay_ms(100);
	PORTB |= (1<<PB3);
	_delay_ms(100);
	PORTB |= (1<<PB4);
	PORTB &= ~(1<<PB3);
	_delay_ms(100);
	PORTB &= ~(1<<PB3);
	PORTB &= ~(1<<PB4);
}

ISR(TIMER0_OVF_vect)
{
	debounce();
}

int main(void)
{
	char Data_in;
	DDRD |= (1<<PD2);//done
	DDRD |= (1<<PD3);
	DDRD |= (1<<PD4);
	DDRD |= (1<<PD5);
	PORTD &= ~(1<<PD2);
	PORTD &= ~(1<<PD3);
	PORTD &= ~(1<<PD4);
	PORTD &= ~(1<<PD5);

	DDRB = 0xff;//done
	PORTB |= (1<<PB0);
	PORTB |= (1<<PB1);
	PORTB &= ~(1<<PB2);
	PORTB &= ~(1<<PB3);
	PORTB &= ~(1<<PB4);
    PORTB &= ~(1<<PB5);
    PORTB &= ~(1<<PB6);
    PORTB &= ~(1<<PB7);

	DDRC = 0xff;//done
	PORTC &= ~(1<<PC0);
	PORTC &= ~(1<<PC1);
	PORTC &= ~(1<<PC2);
	PORTC |= (1<<PC3);
	PORTC &= ~(1<<PC4);
	PORTC |= (1<<PC5);
	PORTC &= ~(1<<PC6);

    USART_Init(9600);						/* initialize USART with 9600 baud rate */
	// Timer0 normal mode, presc 1:256
	TCCR0 = 1<<CS02;
	// Overflow interrupt. (at 8e6/256/256 = 122 Hz)
	TIMSK = 1<<TOIE0;
	debounce_init();
	sei();
    /* Replace with your application code */
    while (1)
    {
		Data_in = USART_RxChar();						/* receive data from Bluetooth device*/
		PORTC ^= (1<<PC1);//power led
		_delay_ms(500);

		if (button_down(BUTTON1_MASK))
		{
			PORTC ^= (1<<PC5);
			PORTC ^= (1<<PC4);
			flasher();
		}
		if (button_down(BUTTON2_MASK))
		{
			PORTC ^= (1<<PC3);
			PORTC ^= (1<<PC2);
			flasher();
		}
		if (button_down(BUTTON3_MASK))
		{
		   PORTB ^= (1<<PB1);
		   PORTB ^= (1<<PB2);
		   flasher();
		}
		if (button_down(BUTTON4_MASK))
		{
		    PORTB ^= (1<<PB0);
		    PORTD ^= (1<<PD7);
			flasher();
		}

		if(Data_in =='1')//button_1_0n
		{
			PORTC |= (1<<PC5);
			PORTC |= (1<<PC4);
			flasher();
			USART_SendString("OUTPUT_1_ON");					

		}
		if(Data_in =='2')//button_1_off
		{
			PORTC &= ~(1<<PC5);
			PORTC &= ~(1<<PC4);
			flasher();
			USART_SendString("OUTPUT_1_OFF");
		}
		if(Data_in =='3')//button_2_0n
		{
			PORTC |= (1<<PC3);
			PORTC |= (1<<PC2);
			flasher();
			USART_SendString("OUTPUT_2_ON");

		}
		if(Data_in =='4')//button_2_off
		{
			PORTC &= ~(1<<PC3);
			PORTC &= ~(1<<PC2);
			flasher();
			USART_SendString("OUTPUT_2_OFF");
		}
		if(Data_in =='5')//button_3_0n
		{
			PORTB |= (1<<PB1);
			PORTB |= (1<<PB2);
			flasher();
			USART_SendString("OUTPUT_3_ON");

		}
		if(Data_in =='6')//button_3_off
		{
			PORTB &= ~(1<<PB1);
			PORTB &= ~(1<<PB2);
			flasher();
			USART_SendString("OUTPUT_3_OFF");
		}
		if(Data_in =='7')//button_4_0n
		{
			PORTB |= (1<<PB0);
			PORTD |= (1<<PD7);
			flasher();
			USART_SendString("OUTPUT_4_ON");

		}
		if(Data_in =='8')//button_4_off
		{
			PORTB &= ~(1<<PB0);
			PORTD &= ~(1<<PD7);
			flasher();
			USART_SendString("OUTPUT_4_OFF");
		}
    }
}

 

This topic has a solution.

anshumaan kumar

Last Edited: Thu. Jan 30, 2020 - 02:11 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
USART_RxChar()

Is that function blocking one? (does it wait in a loop until character is received?)

 

That would explain why it seems that only commands from phone work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good Grief!!

 

First is to get that 'debounce()' out of the ISR.

The rest of it....surprise

 

JIm

 

EDIT:  Where is your timer function anyway?

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Mon. Jan 27, 2020 - 05:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JoniS wrote:
Is that function blocking one? (does it wait in a loop until character is received?)

I am afraid it is. It didn't came into my mind but yeah i had thought of it but could find a much elegant solution to that . Can you guide me  how can I convert this function into a non- blocking one! I will try to do it until you answer

jgmdesign wrote:
The rest of it....surprise

What of it ?? You are scaring me man! Is it not good ??indecision

Thanks for answering .!

anshumaan kumar

Last Edited: Mon. Jan 27, 2020 - 05:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
EDIT:  Where is your timer function anyway?

Wait for a second !I have used a pre-made library found on the site it's good works flawlessly.Actually it was  a tutorial of how to debounce inputs.

https://www.avrfreaks.net/forum/tutsofthard-button-debouncing-software?skey=snigelen

anshumaan kumar

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Anshumaan wrote:
What of it ?? You are scaring me man! Is it not good ??

 

For starters all those delay() calls.  This 'Holds Up' the AVR, when it could be processing other things....like button inputs.

 

You have timer(s), and you have Interrupts.  Use them.

 

Also WRITE out what you want to do on a PC(Paper Computer).  What has priority?  The buttons, or the USART?  Write your code for the primary function >>USART or Buttons<<  THEN ad the fluff.  THis is where the interrupts come in handy.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Anshumaan wrote:

jgmdesign wrote:
EDIT:  Where is your timer function anyway?

Wait for a second !I have used a pre-made library found on the site it's good works flawlessly.Actually it was  a tutorial of how to debounce inputs.

https://www.avrfreaks.net/forum/tutsofthard-button-debouncing-software?skey=snigelen

 

I remember that thread!

 

BUT, nowhere do I remember it saying to call DEBOUNCE() from an ISR.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
You have timer(s), and you have Interrupts.  Use them.

Affirmative. Told you about the code in the beginning this was the last frustrated attempt taking things back to the cellular level to make them work but this attempt also went in vain. Give me some time to do it, I will be bring it back to normal in few hours or so . I will present the code tomorrow.

 

jgmdesign wrote:
BUT, nowhere do I remember it saying to call DEBOUNCE() from an ISR.
 

I am extremely sorry when I feel that it's not going to work I do crazy things. Need to reset myself for a night I will correct any mistakes that would come into my sight. Thanks for the quick response.

 

 

anshumaan kumar

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using the timer IRQ for debouncing is ok & perhaps even good, as long as the buttons themselves don't generate the IRQ's (only the timer tick generates the IRQs)....then the timer can read the inputs & if they are high/low for long enough (enough ticks), call it pressed/not pressed, using a flag bit, or byte (if you don't care about waste).

 

I like to have a count for each switch.  If it reads hi, count up (limit to a max value, say 50), if it is low, count down (limit to zero min)...if count >, say 30, make the button state flag high, if count <, say 15, make the button state flag low.  In between these values, don't change the flag. This is the flag main uses to say whether the button is considered pressed or not. There are many other similar schemes, some better & worse. This assumes a 1ms tick.

 

What are you doing here:

	PORTD &= ~(1<<PD2);
	PORTD &= ~(1<<PD3);
	PORTD &= ~(1<<PD4);
	PORTD &= ~(1<<PD5);

Make it ONE line.  use PORTD = what you want to set up.  Direct, to the point, and no chance for error (&= gives some unnecessary ambiguity using previous values). Use &= only if you have to.

The entire ports init will only be 3 or 4 lines of code!!

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Jan 27, 2020 - 06:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JoniS wrote:

Is that function blocking one? (does it wait in a loop until character is received?)

 

That would explain why it seems that only commands from phone work.

You know what JoniS you have hinted me right I would found it after a very long time but you have hinted me to the very right place.. I have now implement a interrupt based Usart character receiving code and you know it worked .. Thanks a lot for helping you have saved me days even weeks .smiley

 

jgmdesign wrote:
BUT, nowhere do I remember it saying to call DEBOUNCE() from an ISR.

Sorry to question you even I thought that you are saying right at first but then I took a close look at the pdf file of the debounce example given in the end it says that "debounce() is declared static inline
 in debounce.h so we will not suffer from the added overhead of a (external) function call."It works fine staying there in the ISR.

 

avrcandies wrote:
Using the timer IRQ for debouncing is ok & perhaps even good, as long as the buttons themselves don't generate the IRQ's

Thank you avrcandies once again for a great piece of advice.I have implemented what you have said.smiley

 

avrcandies wrote:
Make it ONE line.

Actually what you have seen above was the transformation from the single line to many because I was trying to get it working . You are right many lines for port pin activation leads to error.I have learned it after I have wasted a day or two in some previous project .wink

 

I have done what all of you have said and you know it worked like a charm . Thanks for the great advice all of you.. 

 

anshumaan kumar