Atmega168pa UART receive problem

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

Hello! 

My problem is that i don't really know how to handle the data that i have received.

I'm sending string from PC to my Atmega168pa card via termite. I can receive everything and i can compare the data.

What i basically do is i check if received data is some color red,green,blue and then i check the value it is set to. ex. PC->"red\n"->Atmega atmega sees its red color then PC->100->atmega okay set red color value 100 in pwm.

 

Problems:

1. The VALUE is not set right(something to do with reading the data)

2. After setting one color and value to it, i cant do it anymore.(Maybe once) 

I just dont know how to handle the array when i have once read it.

 

And the code:

 

/*
 * GccApplication1.c
 *
 * Created: 6.7.2017 20.43.27
 * Author : Santtu
 *
 * Atmega168PA-AU uart & pwm
 * Project ColoredPC V2.0
*/

#ifndef F_CPU								// Checks if FOSC is not set earlier in this code
#warning "F_CPU not set so we assume its 16Mhz"				// Throws error message if FOSC is not set
#define F_CPU 16000000UL 						// Set FOSC value 16Mhz
#endif				

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

void UART_init(uint32_t baud);
void PWM_init();
void Fan_set(uint8_t Fan, uint8_t Fan_value);
void RGB_value(uint8_t R, uint8_t G, uint8_t B, uint8_t Brightness);
void UART_Compare();
void register_bits();
void LED1(uint8_t LED);
void UART_Send(unsigned char c, uint8_t times);

#define GREEN OCR1B
#define FAN1 OCR2A
#define FAN2 OCR2B
#define BLUE  OCR0A
#define FAN3 OCR0B
#define RED OCR1A

volatile unsigned char Color_Brightness;
volatile char received_data;
volatile char data[10];
volatile uint8_t data_Ready = 0;
volatile uint8_t i = 0;
volatile uint8_t Ready = 0;

ISR(USART_RX_vect)					                // Interrupt occurs when there is data available in UDR register
{
	LED1(1);			                                // LED ON to indicate that RX is receiving

	if(Ready != 0)						        // If some color or fan is selected then change that device value
	{
		LED1(0);
		Color_Brightness = UDR0;                                // i think the color is set to the first number that occurs so if i've sent 100 it puts the value to 1
		Set_value();
	}

	received_data = UDR0;

	if(received_data == '\n')					// Keep receiving until we get '\n'
	{
		LED1(0);
		data_Ready = 1;						// This indicates that data is ready to be compared in UART_Compare function
		i = 0;
	}
	else
		data[i++] = received_data;

	if(i >= 10)                                                     // This propably causes some problems when reading the data?
	{							        // If array goes over limit, then its value is set to 0
		i = 0;
	}
}

ISR(TIMER0_OVF_vect)
{

}

int main(void)
{
	/* Settings */
	register_bits(1);
	UART_init(9600);
	PWM_init();

	BLUE = 255;                                                     // Set all colors OFF
	GREEN = 255;
	RED = 255;

	while(1)
	{

		if(data_Ready != 0)					// In interrupt we set data_Ready to 1 when we receive '\n'
		{
			UART_Compare();					// So when it is 1 or something else
		}

	}
}

void register_bits()
{
	DDRC = 0b11111111;
	DDRB = 0b00111001;
	DDRD = 0b01100010;
}

void UART_init(uint16_t baud)						// uint16_t baud is desired baudrate
{
	uint16_t ubrr = F_CPU/16/baud-1;				// Calculate the right value for UBBR register (register name may vary!)
	UBRR0H = (unsigned char) (ubrr>>8);				// Set baud rate
	UBRR0L = (unsigned char) ubrr;
	UCSR0B = (1<<RXEN0) | (1<<TXEN0);				// Enable receiver and transmitter
	UCSR0C = (1<<USBS0) | (3<<UCSZ00);				// Set frame format: 8databits, 2 stop bits
	UCSR0B |= (1<<RXCIE0);
	sei();
}

void PWM_init()
{
	DDRB |= (1 << DDB1) | (1 << DDB2) | (1 << DDB3); // OC1A, OC1B, OC2A Set as Output
	DDRD |= (1 << DDD6) | (1 << DDD5) | (1 << DDD3); // OC0A, OC0B, OC2B Set as Output

	TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00);	// Fast PWM mode and Non-inverting
	TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM12) | (1 << WGM10);
	TCCR2A = (1 << COM2A1) | (1 << COM2B1);			

	TCCR0B = (1 << CS01);							// Prescaler 8
	TCCR1B = (1 << CS11);
	TCCR2B = (1 << CS21);							

	TIMSK0 = (1 << TOIE0);

}

// Not using this function yet
void Fan_set(uint8_t Fan, uint8_t Fan_value)
{
	switch(Fan)
	{
		case 1:
			FAN1 = Fan_value;
		break;

		case 2:
			FAN2 = Fan_value;
		break;

		case 3:
			FAN3 = Fan_value;
		break;

		default: ;/* Uart sends message that command is wrong */
		break;
	}

}

void RGB_value(uint8_t R, uint8_t G, uint8_t B, uint8_t Brightness)
{
	if(R == 1 && G == 1 && B == 1)
	{
		RED = Brightness;
		GREEN = Brightness;
		BLUE = Brightness;
	}

	else if(R == 1 && G == 1)
	{
		RED = Brightness;
		GREEN = Brightness;
	}

	else if(R == 1 && B == 1)
	{
		RED = Brightness;
		BLUE = Brightness;
	}

	else if(G == 1 && B == 1)
	{
		GREEN = Brightness;
		BLUE = Brightness;
	}

	else if(R == 1)
	{

		RED = Brightness;
	}

	else if(G == 1)
	{

		GREEN = Brightness;
	}

	else if(B == 1)
	{

		BLUE = Brightness;
	}

	else  ; // Send message via uart
}

void UART_Compare()
{
	if (strcmp(data, "red") == 0)
		Ready = 1;
	else if (strcmp(data, "green") == 0)
		Ready = 2;
	else if (strcmp(data, "blue") == 0)
		Ready = 3;
	else if (strcmp(data, "fan") == 0)
		Ready = 4;
	data_Ready = 0;

}

void Set_value()
{
	LED1(1);
	if(Ready == 1)
	{
		RGB_value(1,0,0,Color_Brightness);//LED COLOR RED
	}
	else if(Ready == 2)
	{
		RGB_value(0,1,0,Color_Brightness);//LED COLOR GREEN
	}
	else if(Ready == 3)
	{
		RGB_value(0,0,1,Color_Brightness);//LED COLOR BLUE
	}
}

void LED1(uint8_t LED)
{
	if(LED == 1)
		PORTC = (1 << PORTC0);
	else PORTC = (0 << PORTC0);
}

My board has USB port and it has FTDI chip which way im communicating to pc and it works fine.

My plan is to make Visual Basic/C# program to control RGB strip and 3 Fans! 

Last Edited: Sun. Jul 16, 2017 - 07:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you should only receive data and set the flags inside ISR. Do all the tasks outside it according to your flags.
.
MG

I don't know why I'm still doing this hobby

Last Edited: Sun. Jul 16, 2017 - 08:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To use Strcmp function you should null terminate('\0') the array/string, http://www.cplusplus.com/referen...

 

Or another way would be to use strncmp instead, so you tell it to only compare X first chars in the array, syntax is almost identical, you just pass uint8_t value indicating max. amount of characters to compare http://www.cplusplus.com/referen...

 

Code editor seems to be broken on tablet+chrome so i cannot give examples.

Last Edited: Sun. Jul 16, 2017 - 08:27 AM