-
- /*
- * target cpu: atmega168
- * registers like UCSR0A are named differently on a atmega32 for example, watch out!
- *
- * this code receives data over the uart from a HC-05 bluetooth module
- * and switches on led1 if the character that was received is: h
- * and led2 if the character is z
- *
- *
- * ----
- * tested with:
- * bluetooth terminal
- * qwerty.bluetooth terminal
- *
- * i know the name looks stupid, but thats how the coder decided to go
- * https://play.google.com/store/apps/details?id=Qwerty.BluetoothTerminal&hl=en
- *
- * version: 6.1104
- * e-mail: aries156@gmail.com
- *
- * in the setup, activate '\r\n' line endings
- * note: tested other bluetooth apps, but this free one just worked
- *
- * to use the software:
- * ONLY THE FIRST TIME: you need to "pair" the devices - for whatever reason, bluetooth likes to get to know each other
- * when you first make contact (like that worked out with the bork) - so you "pair" your device with a PIN code.
- * the hc05 modules pin code is the extremely secure "1234" just to make pairing absolutely useless. (from a security point of view)
- *
- *
- * start the app, choose: connect a device - insecure
- * select your hc-05 module (default name: HC-05)
- * type a h to activate led1
- * type a z to activate led2
- * ----
- *
- * circuit:
- * hc05 rx -> atmega168 tx (PD1)
- * hx05 tx -> atmega168 rx (PD0)
- *
- * voltages:
- * 5V supply voltage:
- * i was running the circuit at 5V, so i needed a voltage devider between the atmega TX and the HC05 RX
- * to get the voltage down from 5v to about 3.3v
- *
- * the modules operating voltage is 3.3v - 6v, so yes you can attach 5v to VCC of the module
- * but the voltage for the RX on the HC05 is 3.3V - so do a voltage divider
- * 3.3v supply voltage:
- * NOT TESTED, but should work just fine. skip the voltage divider.
- *
- * ----
- *
- *
- *
- * code by: julius junghans
- */
-
-
-
- // atmega 168
-
-
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include <string.h>
-
- // you always read online that the modules are preset to 9600 bauds, i just found one source who said otherwies.
- // but that source could have been confused by the fact that the AT command mode works with 38400
- #define BAUD 9600
- /*
- * dont forget to define F_CPU in the Makefile.
- * something like:
- * F_OSC = 16000000
- * F_CPU = $(F_OSC)
- * CFLAGS = -mmcu=$(DEVICE) -DF_CPU=$(F_CPU)
- *
- * sometimes F_OSC is used, probably just another name for F_CPU
- */
-
- #define MYUBRR ((uint16_t) ((F_CPU / ((BAUD) * 16.0)) + .5) - 1)
- #define LED1 PB0
- #define LED2 PC5
-
-
- // contains what the bluetooth module received
- uint8_t data;
-
- void USART_Init(unsigned int ubrr)
- {
- // set baud rate
- UBRR0H = (unsigned char)(ubrr>>8);
- UBRR0L = (unsigned char)(ubrr);
- // enable receiver, transmitter and interrupts for rx/tx
- UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<< TXCIE0);
- // frame format: 8 bits data, 1 stop bit, no parity - these are the default settings for atmega168.
- // no change needed
- // could be changed here: //(0<<UPM00) not tested
- // UCSR0C = (1<<UCSZ00) | (1<<UCSZ01) | (0<<UPM00) | (0<<UPM01);
-
- }
-
- void USART_transmit(char c)
- {
- // the commented out test if we are ready to send should work too
- //while ((UCSR0A & (1 << UDRE0)) == 0) {};
- while ( !(UCSR0A & (1<<UDRE0)) ) {}
- UDR0 = c;
- }
-
-
-
- //char char_array[] = {'a','b','c','\r','\n',0x00};
-
-
- /*void send_string(char s[])
- {
- int i =0;
-
- while (s[i] != 0x00) {
- USART_transmit(s[i]);
- i++;
- }
- }*/
-
-
- /*
- * turn on led1 and led2, wait 200ms, turn them off - do this three times
- * looks like a flashing led
- */
- void flash_leds(void) {
- for (int n=0; n<3; n++) {
- PORTB |= (1 << LED1); // Turn on LED1
- PORTC |= (1 << LED2); // Turn on LED2
- _delay_ms(200);
- PORTB &= ~(1 << LED1); // Turn off LED1
- PORTC &= ~(1 << LED2); // Turn off LED2
- _delay_ms(200);
- }
- }
-
-
- int main(void)
- {
-
- DDRB |= (1 << LED1);
- DDRC |= (1 << LED2);
- // led test
- // turn on both leds (LEDx is defined at the start of the code) to see if we did setup the
- // ports/pins correctly and if they are really connected in the circuit
- // turn them off 3 seconds later
- // note: if you compiled your code with F_CPU=8000000 but the chip is really running with a 16Mhz Crystal,
- // they will not stay on for 3 seconds....they will go out earlier.
-
- PORTB |= (1 << LED1); // Turn on LED1
- PORTC |= (1 << LED2); // Turn on LED2
- _delay_ms(3000);
- PORTB &= ~(1 << LED1); // Turn off LED1
- PORTC &= ~(1 << LED2); // Turn off LED2
-
- sei();
-
- USART_Init(MYUBRR);
- _delay_ms(10);
-
- while(1){}
- }
-
-
- // this is the interrupt service routine for receiving (its named differently on atmega32 for example)
- ISR(USART_RX_vect)
- {
- data = UDR0;
- if (data == 'h') {
- PORTB |= (1 << LED1); // Turn on LED1
- PORTC &= ~(1 << LED2); // Turn off LED2
- }
- else if (data == 'z') {
- PORTB &= ~(1 << LED1); // Turn off LED1
- PORTC |= (1 << LED2); // Turn on LED2
- }
- // the terminal app terminates each string with '\r\n' - the windows way of a newline
- // (linux only uses '\n')
- // so, if we dont skip '\n' and '\r' here and send z led1 will go on for some microseconds? or shorter
- // - you wont see led 1 going on.
- // because after the code read the z it will immediately receive the next character, which is a '\r'
- // and the leds will blink. same for '\n'
- else if (data == '\n') {
- // do nothing
- }
- else if (data == '\r') {
- // do nothing
- }
- else {
- //send_string(data);
- flash_leds();
- }
- }
-
-
- // same as above for transfer
- ISR(USART_TX_vect)
- {
- data = 0;
- PORTB &= ~(1 << LED1); // Turn off LED1
- PORTC |= (1 << LED2); // Turn on LED2
- }
-