├── ADC in Atmega328p ├── flow chart.jpg ├── circuit diagram.jpg ├── Project_image001.jpg ├── main.c └── README.md ├── Threading and Timers in Atmega328p ├── Project_image001.jpg ├── Project_image002.jpg ├── circuit diagram.jpg ├── timming diagram.jpg ├── pattern for thread1.jpg ├── pattern for thread2.jpg ├── lcd.h ├── main.c ├── lcd.c └── README.md ├── Surveillance Car Controlled via DTMF ├── Project_image001.jpg ├── Project_image002.jpg ├── Project_image003.jpg ├── circuit diagram.jpg ├── source_code │ └── source_code.ino └── README.md ├── AVR(atmega328p) Library for LCD JHD162A ├── Project_image001.jpg ├── Project_image002.jpg ├── circuit diagram.jpg ├── lcd.h ├── main.c ├── lcd.c └── README.md ├── Adaptive Screen Brightness using LDR and Python Script ├── Project_image001.jpg ├── Project_image002.jpg ├── cicuit diagram.jpg ├── uartLibrary.h ├── python_serial.py ├── main.c └── README.md ├── Controlling Mouse Pointer using Python Script and Accelerometer ├── Project_image001.jpg ├── Project_image002.jpg ├── Project_image003.jpg ├── circuit diagram.jpg ├── python_serial.py ├── uartLibrary.h ├── main.c └── README.md ├── Reaction Time Game using External and Pin Change Interrupts in Atmega328p ├── Reg1.png ├── Reg2.png ├── Reg3.png ├── Reg4.png ├── Project_image001.jpg ├── Project_image002.jpg ├── circuit diagram.jpg ├── lcd.h ├── README.md ├── lcd.c └── main.c └── Swapping Workspace in Ubuntu using Accelerometer and Python Script ├── Project_image001.jpg ├── Project_image002.jpg ├── Project_image003.jpg ├── circuit diagram.jpg ├── uartLibrary.h ├── python_serial.py ├── main.c └── README.md /ADC in Atmega328p/flow chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/ADC in Atmega328p/flow chart.jpg -------------------------------------------------------------------------------- /ADC in Atmega328p/circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/ADC in Atmega328p/circuit diagram.jpg -------------------------------------------------------------------------------- /ADC in Atmega328p/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/ADC in Atmega328p/Project_image001.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Threading and Timers in Atmega328p/Project_image001.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Threading and Timers in Atmega328p/Project_image002.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Threading and Timers in Atmega328p/circuit diagram.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/timming diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Threading and Timers in Atmega328p/timming diagram.jpg -------------------------------------------------------------------------------- /Surveillance Car Controlled via DTMF/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Surveillance Car Controlled via DTMF/Project_image001.jpg -------------------------------------------------------------------------------- /Surveillance Car Controlled via DTMF/Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Surveillance Car Controlled via DTMF/Project_image002.jpg -------------------------------------------------------------------------------- /Surveillance Car Controlled via DTMF/Project_image003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Surveillance Car Controlled via DTMF/Project_image003.jpg -------------------------------------------------------------------------------- /Surveillance Car Controlled via DTMF/circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Surveillance Car Controlled via DTMF/circuit diagram.jpg -------------------------------------------------------------------------------- /AVR(atmega328p) Library for LCD JHD162A/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/AVR(atmega328p) Library for LCD JHD162A/Project_image001.jpg -------------------------------------------------------------------------------- /AVR(atmega328p) Library for LCD JHD162A/Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/AVR(atmega328p) Library for LCD JHD162A/Project_image002.jpg -------------------------------------------------------------------------------- /AVR(atmega328p) Library for LCD JHD162A/circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/AVR(atmega328p) Library for LCD JHD162A/circuit diagram.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/pattern for thread1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Threading and Timers in Atmega328p/pattern for thread1.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/pattern for thread2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Threading and Timers in Atmega328p/pattern for thread2.jpg -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Adaptive Screen Brightness using LDR and Python Script/Project_image001.jpg -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Adaptive Screen Brightness using LDR and Python Script/Project_image002.jpg -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/cicuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Adaptive Screen Brightness using LDR and Python Script/cicuit diagram.jpg -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Controlling Mouse Pointer using Python Script and Accelerometer/Project_image001.jpg -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Controlling Mouse Pointer using Python Script and Accelerometer/Project_image002.jpg -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/Project_image003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Controlling Mouse Pointer using Python Script and Accelerometer/Project_image003.jpg -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Controlling Mouse Pointer using Python Script and Accelerometer/circuit diagram.jpg -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg1.png -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg2.png -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg3.png -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Reg4.png -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Swapping Workspace in Ubuntu using Accelerometer and Python Script/Project_image001.jpg -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Swapping Workspace in Ubuntu using Accelerometer and Python Script/Project_image002.jpg -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/Project_image003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Swapping Workspace in Ubuntu using Accelerometer and Python Script/Project_image003.jpg -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Swapping Workspace in Ubuntu using Accelerometer and Python Script/circuit diagram.jpg -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Project_image001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Project_image001.jpg -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Project_image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /Project_image002.jpg -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /circuit diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/varun13169/Engineers_Garage/HEAD/Reaction Time Game using External and Pin Change Interrupts in Atmega328p /circuit diagram.jpg -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/lcd.h: -------------------------------------------------------------------------------- 1 | void start(); 2 | void command(char); 3 | void data(char); 4 | void Send_A_String(char *StringOfCharacters); 5 | void cut(char *str); 6 | void Send_An_Integer(int x); 7 | void setCursor(int row,int column); 8 | void clearScreen(); 9 | void home(); 10 | void cursor(); 11 | void noCursor(); 12 | void blink(); 13 | void noBlink(); 14 | void display(); 15 | void noDisplay(); 16 | void scrollDisplayLeft(); 17 | void scrollDisplayRight(); 18 | void autoscroll(); 19 | void noAutoscroll(); 20 | void createChar(int num,unsigned int *charArray); 21 | 22 | -------------------------------------------------------------------------------- /AVR(atmega328p) Library for LCD JHD162A/lcd.h: -------------------------------------------------------------------------------- 1 | void start(); 2 | void command(char); 3 | void data(char); 4 | void Send_A_String(char *StringOfCharacters); 5 | void cut(char *str); 6 | void Send_An_Integer(int x); 7 | void setCursor(int row,int column); 8 | void clearScreen(); 9 | void home(); 10 | void cursor(); 11 | void noCursor(); 12 | void blink(); 13 | void noBlink(); 14 | void display(); 15 | void noDisplay(); 16 | void scrollDisplayLeft(); 17 | void scrollDisplayRight(); 18 | void autoscroll(); 19 | void noAutoscroll(); 20 | void createChar(int num,unsigned int *charArray); 21 | 22 | -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /lcd.h: -------------------------------------------------------------------------------- 1 | void start(); 2 | void command(char); 3 | void data(char); 4 | void Send_A_String(char *StringOfCharacters); 5 | void cut(char *str); 6 | void Send_An_Integer(int x); 7 | void setCursor(int row,int column); 8 | void clearScreen(); 9 | void home(); 10 | void cursor(); 11 | void noCursor(); 12 | void blink(); 13 | void noBlink(); 14 | void display(); 15 | void noDisplay(); 16 | void scrollDisplayLeft(); 17 | void scrollDisplayRight(); 18 | void autoscroll(); 19 | void noAutoscroll(); 20 | void createChar(int num,unsigned int *charArray); 21 | 22 | -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/python_serial.py: -------------------------------------------------------------------------------- 1 | ################################################################################################################################## 2 | # varun13169 # 3 | ################################################################################################################################## 4 | 5 | import serial # http://pyserial.sourceforge.net/ , Version: 2.7 6 | import autopy # http://autopy.org , Version: 0.51 7 | 8 | ser = serial.Serial('/dev/ttyUSB0',9600) # This is for Linux for Windows select the respective COM port 9 | 10 | # My screen's resolution in pixels, 11 | # you might want to change it. 12 | # 1365x767 13 | 14 | 15 | while(1): 16 | try: 17 | accelerometerReading = map(int,ser.readline().split()) 18 | autopy.mouse.move(accelerometerReading[1],accelerometerReading[0]) 19 | print accelerometerReading 20 | 21 | except: 22 | None 23 | 24 | ############################################################# END ################################################################## 25 | -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/uartLibrary.h: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #define BAUD 9600 3 | #define BRC ((F_CPU/16/BAUD)-1) 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void uart_init() 11 | { 12 | UBRR0H = (BRC>>8); //Putting Upper 4 bits of BRC in lower 4 bits of UBRR0H 13 | UBRR0L = BRC; //Putting Lowwer 8 bits of BRC in UBRR0L 14 | 15 | UCSR0B = 1 << TXEN0 | 1 << TXCIE0 | 1 << RXEN0 | 1 << RXCIE0; //Enables TX, TX complete Interupt Enable, Enable RX, RX complete Interupt Enable 16 | UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); //8-bit data size 17 | } 18 | 19 | void uart_putchar(char c, FILE *stream) 20 | { 21 | if (c == '\n') 22 | { 23 | uart_putchar('\r', stream); 24 | } 25 | loop_until_bit_is_set(UCSR0A, UDRE0); // Wait until data register empty. 26 | UDR0 = c; 27 | 28 | } 29 | 30 | char uart_getchar(FILE *stream) 31 | { 32 | loop_until_bit_is_set(UCSR0A, RXC0); 33 | return UDR0; 34 | } 35 | 36 | FILE uart_output = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); 37 | 38 | FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); 39 | 40 | 41 | -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/uartLibrary.h: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #define BAUD 9600 3 | #define BRC ((F_CPU/16/BAUD)-1) 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void uart_init() 11 | { 12 | UBRR0H = (BRC>>8); //Putting Upper 4 bits of BRC in lower 4 bits of UBRR0H 13 | UBRR0L = BRC; //Putting Lowwer 8 bits of BRC in UBRR0L 14 | 15 | UCSR0B = 1 << TXEN0 | 1 << TXCIE0 | 1 << RXEN0 | 1 << RXCIE0; //Enables TX, TX complete Interupt Enable, Enable RX, RX complete Interupt Enable 16 | UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); //8-bit data size 17 | } 18 | 19 | void uart_putchar(char c, FILE *stream) 20 | { 21 | if (c == '\n') 22 | { 23 | uart_putchar('\r', stream); 24 | } 25 | loop_until_bit_is_set(UCSR0A, UDRE0); // Wait until data register empty. 26 | UDR0 = c; 27 | 28 | } 29 | 30 | char uart_getchar(FILE *stream) 31 | { 32 | loop_until_bit_is_set(UCSR0A, RXC0); 33 | return UDR0; 34 | } 35 | 36 | FILE uart_output = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); 37 | 38 | FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); 39 | 40 | 41 | -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/uartLibrary.h: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #define BAUD 9600 3 | #define BRC ((F_CPU/16/BAUD)-1) 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void uart_init() 11 | { 12 | UBRR0H = (BRC>>8); //Putting Upper 4 bits of BRC in lower 4 bits of UBRR0H 13 | UBRR0L = BRC; //Putting Lowwer 8 bits of BRC in UBRR0L 14 | 15 | UCSR0B = 1 << TXEN0 | 1 << TXCIE0 | 1 << RXEN0 | 1 << RXCIE0; //Enables TX, TX complete Interupt Enable, Enable RX, RX complete Interupt Enable 16 | UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); //8-bit data size 17 | } 18 | 19 | void uart_putchar(char c, FILE *stream) 20 | { 21 | if (c == '\n') 22 | { 23 | uart_putchar('\r', stream); 24 | } 25 | loop_until_bit_is_set(UCSR0A, UDRE0); // Wait until data register empty. 26 | UDR0 = c; 27 | 28 | } 29 | 30 | char uart_getchar(FILE *stream) 31 | { 32 | loop_until_bit_is_set(UCSR0A, RXC0); 33 | return UDR0; 34 | } 35 | 36 | FILE uart_output = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); 37 | 38 | FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); 39 | 40 | 41 | -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/python_serial.py: -------------------------------------------------------------------------------- 1 | ################################################################################################################################## 2 | # varun13169 # 3 | ################################################################################################################################## 4 | 5 | import serial # http://pyserial.sourceforge.net/ , Version: 2.7 6 | import sys 7 | 8 | ser = serial.Serial('/dev/ttyUSB0',9600) # This is for Linux for Windows select the respective COM port 9 | 10 | path='/sys/class/backlight/intel_backlight/brightness' # This is the path to the file from where I can adjust the brightness 11 | # you can also check this link for more information: 12 | # http://askubuntu.com/questions/56155/how-can-i-change-brightness-through-terminal 13 | 14 | 15 | 16 | while(1): 17 | try: 18 | value = map(str,ser.readline().split()) 19 | f = open(path,'w') # Open the file 20 | f.write(value[0]) # Edit it by writing in the value 21 | f.close() # Save it by closing it 22 | print value # prints the list for debugging purpose 23 | 24 | except: 25 | None 26 | # Just to take care of initial garbage values 27 | 28 | 29 | ############################################################# END ################################################################## 30 | -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/python_serial.py: -------------------------------------------------------------------------------- 1 | ################################################################################################################################## 2 | # varun13169 # 3 | ################################################################################################################################## 4 | 5 | import serial # http://pyserial.sourceforge.net/ , Version: 2.7 6 | import subprocess 7 | import sys 8 | 9 | 10 | ser = serial.Serial('/dev/ttyUSB0',9600) # This is for Linux for Windows select the respective COM port 11 | 12 | 13 | try: 14 | bashCommand = "wmctrl -d" 15 | process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) 16 | output = process.communicate()[0] 17 | print output 18 | except: 19 | print '''The program 'wmctrl' is currently not installed. You can install it by typing: 20 | sudo apt-get install wmctrl''' 21 | 22 | sys.exit() 23 | 24 | 25 | while(1): 26 | try: 27 | 28 | readingFromArduino = map(int,ser.readline().split()) 29 | 30 | if readingFromArduino[2]==1: 31 | bashCommand= 'wmctrl -o 0,0' 32 | if readingFromArduino[2]==2: 33 | bashCommand= 'wmctrl -o 1366,0' 34 | if readingFromArduino[2]==3: 35 | bashCommand= 'wmctrl -o 0,768' 36 | if readingFromArduino[2]==4: 37 | bashCommand= 'wmctrl -o 1366,768' 38 | else: 39 | None 40 | 41 | print readingFromArduino 42 | process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) 43 | output = process.communicate()[0] 44 | 45 | 46 | except: 47 | #print 'Check Some error is there ......' 48 | None 49 | 50 | ############################################################# END ########################################################### 51 | -------------------------------------------------------------------------------- /ADC in Atmega328p/main.c: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // varun13169 // 3 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 4 | 5 | 6 | /* 7 | Critical point of LDR: 10-15 8 | Critical point of NTC: 130-135 9 | 10 | Critical point for a sensor depends on its make model number and other factors, I have mentioned the range for critical point of my sensors. 11 | */ 12 | 13 | #define F_CPU 16000000UL 14 | #include 15 | #include 16 | #include 17 | 18 | void setup_adc(); 19 | 20 | int main() 21 | { 22 | DDRD = 0xA0; //Set Pin5 and Pin7 on arduino as output 23 | 24 | sei(); //Enales global interrupt 25 | setup_adc(); //Setup ADC according to the defined function 26 | 27 | while(1) {} //Don't let the program to end 28 | } 29 | 30 | 31 | 32 | ISR(ADC_vect) 33 | { 34 | uint8_t adcl = ADCL; //This is an 8-bit varible used to store the value of ADLC 35 | uint16_t adc_ten_bit_value = ADCH<<2 | adcl>>6; //This is an 16-bit varible use to store the 10-bit value of left adjusted result 36 | 37 | int value_of_mux0= ADMUX & 1<133 && (value_of_mux0==0)) {PORTD|=1< 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include"lcd.h" 12 | 13 | void timer(); 14 | int in_counter=0; // keeps track on both the threads and resets when one complete cycle is over 15 | int in_counter1=0; // keeps track on one cycle of thread1 and resets after one cycle of thread1 is over 16 | int in_counter2=0; // keeps track on one cycle of thread2 and resets after one cycle of thread2 is over 17 | 18 | int count1=0; 19 | int count2=0; 20 | 21 | int main(void) 22 | { 23 | DDRB = 0x03; // Declare Pin 8,9 as output 24 | DDRD = 0xF0; // Declare Pin 4,5,6,7 as output 25 | 26 | _delay_ms(500); 27 | start(); // Initialises LCD 28 | 29 | sei(); // Allows interupt 30 | timer(); // Initialises Timer 31 | 32 | command(0x80); // moves the cursor to (1,1) 33 | Send_A_String("0"); // Initialize the LCD by writing Zero at (1,1) 34 | command(0xC0); // moves the cursor to (2,1) 35 | Send_A_String("0"); // Initialize the LCD by writing Zero at (2,1) 36 | 37 | while(1) 38 | {} 39 | return 0; 40 | } 41 | 42 | void timer() 43 | { 44 | OCR1A = 31249; // One tick is used to return to zero 45 | TCCR1B |= (1 << CS02); // prescalar 256 46 | TCCR1B |= (1 << WGM12); // turns on CTC mode for timer1 47 | 48 | TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt 49 | TCNT1 = 0; // 16 bit register 50 | } 51 | 52 | /********************************** ISR ******************************/ 53 | ISR(TIMER1_COMPA_vect) 54 | { 55 | 56 | in_counter++; 57 | 58 | /************* Thread1 Starts **************/ 59 | if(in_counter<=11) 60 | { 61 | in_counter1++; 62 | if(in_counter1%2==0) 63 | { 64 | count1++; 65 | command(0x80); 66 | Send_An_Integer(count1); 67 | } 68 | if(in_counter1==22){in_counter1=0;} // One cycle of thread1 is over when in_counter1 equals 22 69 | } 70 | /*************** Thread1 Ends **************/ 71 | 72 | 73 | /************* Thread2 Starts **************/ 74 | if(in_counter>11) 75 | { 76 | in_counter2++; 77 | if(in_counter2%4==0) 78 | { 79 | count2--; 80 | command(0xC0); 81 | Send_An_Integer(count2); 82 | } 83 | if(in_counter2==44){in_counter2=0;} // One cycle of thread2 is over when in_counter2 equals 44 84 | } 85 | /*************** Thread2 Ends **************/ 86 | 87 | 88 | if(in_counter==22) 89 | { 90 | in_counter=0; // One complete cycle is over when in_counter equals 22 91 | } 92 | } 93 | 94 | /*********************************************************** END *******************************************************************/ 95 | 96 | -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/main.c: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // varun13169 // 3 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 4 | 5 | #define F_CPU 16000000UL 6 | #include "uartLibrary.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | /****************** Limits **************/ 14 | #define low_min 0 15 | #define low_max 10 16 | 17 | #define mid_min 10 18 | #define mid_max 30 19 | 20 | #define high_min 30 21 | 22 | #define minimum_brightness 500 23 | #define medium_brightness 2500 24 | #define maximum_brightness 4880 25 | /****************************************/ 26 | /* 27 | You might need to change these limits 28 | according to your Linux machine and LDR 29 | */ 30 | 31 | 32 | int ldrValue=0; 33 | void setup_adc(); 34 | 35 | int main(void) 36 | { 37 | uart_init(); 38 | stdout = &uart_output; 39 | stdin = &uart_input; 40 | 41 | DDRC |= 0x0A; // Set Pin5 and Pin7 on arduino as output 42 | PORTC = 1<>6; //This is an 16-bit varible use to store the 10-bit value of left adjusted result 74 | 75 | ldrValue=adc_ten_bit_value; 76 | 77 | if(low_min<=ldrValue && ldrValue=high_min){printf("%d %d\n", maximum_brightness, ldrValue);} // to my laptop 80 | 81 | ADCSRA |= 1< 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | int xRaw=0,yRaw=0,zRaw=0; 13 | void setup_adc(); 14 | 15 | 16 | int main(void) 17 | { 18 | uart_init(); 19 | stdout = &uart_output; 20 | stdin = &uart_input; 21 | 22 | DDRC = 0x22; //Set Pin5 and Pin7 on arduino as output 23 | PORTC |= 1<290 && yRaw>280){return 1;} 50 | if (xRaw>290 && yRaw<280){return 2;} 51 | if (xRaw<290 && yRaw>320){return 3;} 52 | if (xRaw<290 && yRaw<320){return 4;} 53 | else{return 0;} 54 | } 55 | /*********** varun13169 **************/ 56 | 57 | ISR(ADC_vect) 58 | { 59 | uint8_t adcl = ADCL; //This is an 8-bit varible used to store the value of ADLC 60 | uint16_t adc_ten_bit_value = ADCH<<2 | adcl>>6; //This is an 16-bit varible use to store the 10-bit value of left adjusted result 61 | 62 | int value_of_mux0= ADMUX & 0x0F; // Retains last four bits of ADMUX,starting fom LSB, 63 | // used in workspaceping ADC converted values to xRaw,yRaw,zRaw respectively 64 | 65 | /************ For PORTC2 *************/ 66 | if(value_of_mux0==0x02) 67 | { 68 | xRaw=adc_ten_bit_value; 69 | ADMUX &= 0xF0; // Clears last four bits in ADMUX 70 | ADMUX |= 0x03; // Put the next four bit accrding to the next conversion 71 | } 72 | /*************************************/ 73 | 74 | 75 | /************ For PORTC3 *************/ 76 | if(value_of_mux0==0x03) 77 | { 78 | yRaw=adc_ten_bit_value; 79 | ADMUX &= 0xF0; // Clears last four bits in ADMUX 80 | ADMUX |= 0x02; // Put the next four bit accrding to the next conversion 81 | } 82 | /*************************************/ 83 | 84 | 85 | 86 | // This is for z-axis, as Z-out pin is connected to PORTC4, 87 | // I don't require Z-out but one can easily get it by 88 | // making some small changes 89 | /* 90 | if(value_of_mux0==0x04) 91 | { 92 | zRaw=adc_ten_bit_value; 93 | ADMUX &= 0xF0; 94 | ADMUX |= 0x02; 95 | } 96 | */ 97 | 98 | 99 | 100 | ADCSRA |= 1< 7 | #include 8 | #include 9 | #include 10 | #include "lcd.h" 11 | //D4-D7 connected to D4-D7 12 | 13 | #define rs PB0 //pin8 14 | #define en PB1 //pin9 15 | 16 | 17 | 18 | /**** Decimal Values to Display Special Characters ****/ 19 | unsigned int s1[]={10,21,17,17,17,10,4,0}; 20 | unsigned int s2[]={0,10,0,4,4,17,10,4}; 21 | unsigned int s3[]={0,10,0,4,4,0,14,17}; 22 | unsigned int s4[]={1,3,5,9,9,11,27,24}; 23 | unsigned int s5[]={0,17,10,17,4,0,14,17}; 24 | unsigned int s6[]={0,10,0,4,4,0,31,0}; 25 | unsigned int s7[]={10,0,4,0,14,17,17,14}; 26 | unsigned int s8[]={0,10,0,31,17,14,0,0}; 27 | /******************************************************/ 28 | 29 | int main() 30 | { 31 | int i; 32 | DDRB = 0x03; 33 | DDRD = 0xF0; 34 | 35 | _delay_ms(200); 36 | start(); 37 | 38 | while(1) 39 | { 40 | clearScreen(); 41 | Send_A_String("Send_A_String()"); 42 | _delay_ms(100);////// 43 | while(!(PINB & (1< 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | //These values are from my sensors you might have to change it according to your sensor 14 | #define min_x 295 // approx max. value of x I'm getting from my sensor 15 | #define max_x 395 // approx min. value of x I'm getting from my sensor 16 | #define min_y 295 // approx max. value of y I'm getting from my sensor 17 | #define max_y 390 // approx min. value of y I'm getting from my sensor 18 | #define min_z 295 // approx max. value of z I'm getting from my sensor 19 | #define max_z 422 // approx min. value of z I'm getting from my sensor 20 | /*************************************************************************************/ 21 | 22 | #define height_min 0 23 | #define height_max 767 24 | #define width_min 0 25 | #define width_max 1365 26 | 27 | 28 | int xRaw=0,yRaw=0,zRaw=0; 29 | void setup_adc(); 30 | 31 | 32 | int main(void) 33 | { 34 | uart_init(); 35 | stdout = &uart_output; 36 | stdin = &uart_input; 37 | 38 | DDRC = 0x22; //Set Pin5 and Pin7 on arduino as output 39 | PORTC |= 1< to_high){return to_high;} 72 | else{return a;} 73 | } 74 | /*********** varun13169 **************/ 75 | 76 | ISR(ADC_vect) 77 | { 78 | uint8_t adcl = ADCL; //This is an 8-bit varible used to store the value of ADLC 79 | uint16_t adc_ten_bit_value = ADCH<<2 | adcl>>6; //This is an 16-bit varible use to store the 10-bit value of left adjusted result 80 | 81 | int value_of_mux0= ADMUX & 0x0F; // Retains last four bits of ADMUX,starting fom LSB, 82 | // used in mapping ADC converted values to xRaw,yRaw,zRaw respectively 83 | 84 | /************ For PORTC2 *************/ 85 | if(value_of_mux0==0x02) 86 | { 87 | xRaw=adc_ten_bit_value; 88 | ADMUX &= 0xF0; // Clears last four bits in ADMUX 89 | ADMUX |= 0x03; // Put the next four bit accrding to the next conversion 90 | xRaw = map_contraint(xRaw,min_x,max_x,height_min,height_max); 91 | } 92 | /*************************************/ 93 | 94 | 95 | /************ For PORTC3 *************/ 96 | if(value_of_mux0==0x03) 97 | { 98 | yRaw=adc_ten_bit_value; 99 | ADMUX &= 0xF0; // Clears last four bits in ADMUX 100 | ADMUX |= 0x02; // Put the next four bit accrding to the next conversion 101 | yRaw = map_contraint(yRaw,min_y,max_y,-width_max,width_min); 102 | yRaw = -yRaw; 103 | } 104 | /*************************************/ 105 | 106 | 107 | 108 | // This is for z-axis, as Z-out pin is connected to PORTC4, 109 | // I don't require Z-out but one can easily get it by 110 | // making some small changes 111 | /* 112 | if(value_of_mux0==0x04) 113 | { 114 | zRaw=adc_ten_bit_value; 115 | ADMUX &= 0xF0; 116 | ADMUX |= 0x02; 117 | } 118 | */ 119 | 120 | 121 | 122 | ADCSRA |= 1< 1234 13 | 14 | */ 15 | 16 | 17 | #include 18 | 19 | Servo myservo; 20 | int servo=5; 21 | int angle=180; // 180 is the initial angle and mobile phone should be placed with camera facing front 22 | 23 | int d1=12; 24 | int d2=11; 25 | int d3=10; 26 | int d4=9; 27 | int st=8; 28 | int vccdtmf=13; 29 | 30 | int a=0,s=0,d=0,f=0,flag=0; 31 | 32 | int m11=19; 33 | int m12=18; 34 | int m21=17; 35 | int m22=16; 36 | 37 | int p1=15; 38 | int p2=14; 39 | 40 | 41 | 42 | void setup() 43 | { 44 | myservo.attach(5); // Defines Pin 5 for Servo 45 | myservo.write(angle); 46 | 47 | pinMode(d1,INPUT); 48 | pinMode(d2,INPUT); 49 | pinMode(d3,INPUT); 50 | pinMode(d4,INPUT); 51 | pinMode(st,INPUT); 52 | pinMode(vccdtmf,OUTPUT); 53 | 54 | pinMode(m11,OUTPUT); 55 | pinMode(m12,OUTPUT); 56 | pinMode(m21,OUTPUT); 57 | pinMode(m22,OUTPUT); 58 | 59 | pinMode(p1,OUTPUT); 60 | pinMode(p2,OUTPUT); 61 | 62 | pinMode(servo,OUTPUT); 63 | } 64 | 65 | void loop() 66 | { 67 | digitalWrite(vccdtmf,HIGH); // +5V for DTMF Module 68 | digitalWrite(p1,HIGH); // For Max. speed 69 | digitalWrite(p2,HIGH); // For Max. speed 70 | 71 | 72 | /////////////////////////////////////////////// Loop for Security PIN /// 73 | 74 | while(flag==0) 75 | { 76 | if(a!=1 && digitalRead(d1)==1 && digitalRead(d2)==0 && digitalRead(d3)==0 && digitalRead(d4)==0 && digitalRead(st)==1) 77 | { 78 | a=1; 79 | } 80 | if(a==1 && s!=2 && digitalRead(d1)==0 && digitalRead(d2)==1 && digitalRead(d3)==0 && digitalRead(d4)==0 && digitalRead(st)==1) 81 | { 82 | s=2; 83 | } 84 | if(s==2 && d!=3 && digitalRead(d1)==1 && digitalRead(d2)==1 && digitalRead(d3)==0 && digitalRead(d4)==0 && digitalRead(st)==1) 85 | { 86 | d=3; 87 | } 88 | if(d==3 && f!=4 && digitalRead(d1)==0 && digitalRead(d2)==0 && digitalRead(d3)==1 && digitalRead(d4)==0 && digitalRead(st)==1) 89 | { 90 | f=4; 91 | } 92 | if(a==1 && s==2 && d==3 && f==4) 93 | { 94 | flag=1; 95 | } 96 | } 97 | 98 | ///////////////////////////////////////////////////////////////////////// 99 | 100 | 101 | ///////////////////////////////////////// Movement of Car /////////////// 102 | 103 | while(digitalRead(st)==0) // RESET the value when no valid tone is given 104 | { 105 | digitalWrite(m11,LOW); 106 | digitalWrite(m12,LOW); 107 | digitalWrite(m21,LOW); 108 | digitalWrite(m22,LOW); 109 | } 110 | 111 | while(digitalRead(d1)==0 && digitalRead(d2)==1 && digitalRead(d3)==0 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 2 for Forward Direction 112 | { 113 | digitalWrite(m11,HIGH); 114 | digitalWrite(m12,LOW); 115 | digitalWrite(m21,HIGH); 116 | digitalWrite(m22,LOW); 117 | } 118 | 119 | 120 | while(digitalRead(d1)==1 && digitalRead(d2)==0 && digitalRead(d3)==0 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 1 for Right Forward Direction 121 | { 122 | digitalWrite(m11,HIGH); 123 | digitalWrite(m12,LOW); 124 | digitalWrite(m21,LOW); 125 | digitalWrite(m22,LOW); 126 | } 127 | 128 | while(digitalRead(d1)==1 && digitalRead(d2)==1 && digitalRead(d3)==0 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 3 for Left Forward Direction 129 | { 130 | digitalWrite(m11,LOW); 131 | digitalWrite(m12,LOW); 132 | digitalWrite(m21,HIGH); 133 | digitalWrite(m22,LOW); 134 | } 135 | 136 | while(digitalRead(d1)==1 && digitalRead(d2)==0 && digitalRead(d3)==1 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 5 for Backward Direction 137 | { 138 | digitalWrite(m11,LOW); 139 | digitalWrite(m12,HIGH); 140 | digitalWrite(m21,LOW); 141 | digitalWrite(m22,HIGH); 142 | } 143 | 144 | while(digitalRead(d1)==0 && digitalRead(d2)==0 && digitalRead(d3)==1 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 4 for Right Backward Direction 145 | { 146 | digitalWrite(m11,LOW); 147 | digitalWrite(m12,HIGH); 148 | digitalWrite(m21,LOW); 149 | digitalWrite(m22,LOW); 150 | } 151 | 152 | while(digitalRead(d1)==0 && digitalRead(d2)==1 && digitalRead(d3)==1 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 5 for Left Backward Direction 153 | { 154 | digitalWrite(m11,LOW); 155 | digitalWrite(m12,LOW); 156 | digitalWrite(m21,LOW); 157 | digitalWrite(m22,HIGH); 158 | } 159 | 160 | ///////////////////////////////////////////////////////////////////////// 161 | 162 | 163 | ////////////////////////////////////// Movement of Servo //////////////// 164 | 165 | if(digitalRead(d1)==1 && digitalRead(d2)==1 && digitalRead(d3)==1 && digitalRead(d4)==0 && digitalRead(st)==1) // Press 7 to turn servo in anti-clockwise direction 166 | { 167 | if(angle>0) 168 | { 169 | angle=angle-45; 170 | myservo.write(angle); 171 | delay(500); 172 | } 173 | } 174 | 175 | 176 | if(digitalRead(d1)==0 && digitalRead(d2)==0 && digitalRead(d3)==0 && digitalRead(d4)==1 && digitalRead(st)==1) // Press 8 to turn servo in clockwise direction 177 | { 178 | if(angle<180) 179 | { 180 | angle=angle+45; 181 | myservo.write(angle); 182 | delay(500); 183 | } 184 | } 185 | 186 | ///////////////////////////////////////////////////////////////////////// 187 | 188 | /////////////////////////////////// You Have to Enter Password again //// 189 | 190 | while(digitalRead(d1)==1 && digitalRead(d2)==0 && digitalRead(d3)==1 && digitalRead(d4)==1 && digitalRead(st)==1) //Press A to reset the PIN 191 | { 192 | flag=1; 193 | } 194 | 195 | ///////////////////////////////////////////////////////////////////////// 196 | 197 | } 198 | 199 | /*********************************************************** END *******************************************************************/ 200 | 201 | 202 | -------------------------------------------------------------------------------- /Controlling Mouse Pointer using Python Script and Accelerometer/README.md: -------------------------------------------------------------------------------- 1 | #Controlling Mouse Pointer using Python Script and Accelerometer 2 | 3 | ##Requirements: 4 | * Arduino with Atmega328p
5 | * Accelerometer ADXL335
6 | * Python 2.7 on your machine
7 | * Python libraries: [Pyserial] and [Autopy]
8 | 9 | ##Summary: 10 | There are many ways of controlling mouse pointer using atmega328p, and I find using a python script and an arduino best and effective one because of the following reasons:
11 | 1. Python is a common language and comes pre-installed in almost all LINUX distros.
12 | 2. Using python script makes this project compatible to cross platforms, as no fancy software is needed.
13 | 3. Using an arduino saves me from the trouble that goes into making the whole circuit and then connecting it through a USB to TTL converter.
14 | 15 | I’ll be using two non-standard libraries viz. Pyserial and Autopy both of them are freely available and easy to install, just like any non-standard library.
16 | Accelerometer that I’m using is ADXL335, it’s a triple axis accelerometer.
17 | 18 | 19 | ##Project's Video: 20 | [https://www.youtube.com/watch?v=O0MqSM-0vxk] 21 | 22 | ##Circuit Diagram: 23 | ![alt text][circuit diagram] 24 | 25 | 26 | ##Project Images 27 | ![alt text][Image_1] 28 | ![alt text][Image_2] 29 | ![alt text][Image_3] 30 | 31 | 32 | ##Description: 33 | 34 | ###How I am uploading code into arduino: 35 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
36 | Then, just type these three commands, in the same order, on your terminal / cmd. 37 | 38 | ```sh 39 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os main.c -o main.elf 40 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 41 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 42 | ``` 43 | 44 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 45 | 46 | 47 | ###Little bit about accelerometer being used: 48 | I’m using adxl335 it’s a triple axis accelerometer. It can measure acceleration with a minimum full scale range of +-3g. It can used to measure tilt by measuring static acceleration of gravity or it can measure impact from shock and vibration by measuring dynamic acceleration.
49 | For more details and knowledge you can always look up adxl335 [datasheet].
50 | 51 | ###Source Code: 52 | This program is an application of ADC and serial communication.
53 | I already did explain ADC [here], check it before reading this article.
54 | There are few changes that I made in setup_adc() function and ISR() block.
55 | 56 | In setup_adc() function I set the MUX1 bit in ADMUX register in order to start the conversion of value at PORTC2.
57 | In ISR() block, I first store 10-bit value from ADC in a variable. Then check four bits in ADMUX, starting from LSB, depending on these four bits I decide whether 10-bit value is for x,y,z axis.
58 | Then I set last four bits in ADMUX for next conversion.
59 | After that a map_constaint() function is called. It is a combination of map() function and constraint function() available in Arduino IDE.
60 | It takes 5 arguments, first is the value to be mapped, second is the lowest value on original scale, third is highest value on original scale, fourth is lowest value on the secondary scale, fifth is highest value on the secondary scale.
61 | Then by using simple maths it linearly maps value from primary scale to secondary scale and then apply constraints on it with respect to the secondary scale.
62 | 63 | I’m using uartLibrary.h to send readings from accelerometer to my laptop using serial communication. I build this library referring this [article]. After including this library I can use printf() function from stdio.h to send strings from Atmega358p to my laptop.
64 | For detailed information please check the Source Code it’s well documented.
65 | 66 | ###Explanation of Python Script: 67 | I’m using two libraries [Pyserial] and [Autopy] both of them are freely available.
68 | First I created an object “ser” of “Serial” class and gave two arguments in it
69 | 1. Serial Port: In my case it is '/dev/ttyUSB1'
70 | 2. Baud rate: I my case it’s 9600
71 | 72 | Then in an infinite loop I put a try & except block because initially trash values are send from atmega328p.
73 | In try block I read data being send over serial port then break it and convert it to integer and store it in an array.
74 | Next I feed these values from array to autopy.mouse.move(), it takes two input 1st is width and 2nd is height of your screen both of them in pixels.
75 | Then I print these values on terminal for debugging purposes.
76 | 77 | ###Explanation of Circuit: 78 | As can be seen in images, my accelerometer module don't have a header pin for ST, and all other i/o pins are in straight line. So instead of using a breadboard for connections I simply placed accelerometer on Analog pins of Arduino which maps to PORTC on atmega328p.
79 | For Vcc and GND I declared PORTC1 and PORTC5 as output and pulled down PORTC1 for GND, pulled up PORTC5 for Vcc.
80 | Now I can simply measure acceleration from x,y,z axis on PORTC2,3,4 respectively.
81 | 82 | 83 | 84 | 85 | ##Getting started with this Project 86 | There are three files:
87 | 1. main.c contains the source code for atmega328p side of this application.
88 | 2. uartLibrary.h contains definition of all the functions necessary for serial communication.
89 | 3. python_serial.py it reads data from serial port and controls the mouse pointer.
90 | 91 | Place main.c and uartLibrary.h in same directory, and upload the code to atmega328p.
92 | Now, run the python script and BAAMMM!! you are ready to go. Just move accelerometer and you pointer will start moving.
93 | 94 | 95 | 96 | 97 | ##Published on Engineer's Garage 98 | [http://www.engineersgarage.com/contribution/controlling-mouse-pointer-using-python-script-and-accelerometer] 99 | 100 | 101 | [Pyserial]: http://pyserial.sourceforge.net/ 102 | [Autopy]: http://autopy.org 103 | [datasheet]: https://www.sparkfun.com/datasheets/Components/SMD/adxl335.pdf 104 | [here]: https://github.com/varun13169/Engineers_Garage/tree/master/ADC%20in%20Atmega328p 105 | [article]: http://www.appelsiini.net/2011/simple-usart-with-avr-libc 106 | 107 | [https://www.youtube.com/watch?v=O0MqSM-0vxk]: https://www.youtube.com/watch?v=O0MqSM-0vxk 108 | 109 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/Controlling%20Mouse%20Pointer%20using%20Python%20Script%20and%20Accelerometer/circuit%20diagram.jpg "circuit diagram" 110 | 111 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/Controlling%20Mouse%20Pointer%20using%20Python%20Script%20and%20Accelerometer/Project_image001.jpg "Image_1" 112 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/Controlling%20Mouse%20Pointer%20using%20Python%20Script%20and%20Accelerometer/Project_image002.jpg "Image_2" 113 | [Image_3]: https://github.com/varun13169/Engineers_Garage/blob/master/Controlling%20Mouse%20Pointer%20using%20Python%20Script%20and%20Accelerometer/Project_image003.jpg "Image_3" 114 | 115 | [avr­libc]: http://www.nongnu.org/avr-libc/ 116 | [winAVR]: https://sourceforge.net/projects/winavr/ 117 | 118 | [http://www.engineersgarage.com/contribution/controlling-mouse-pointer-using-python-script-and-accelerometer]: http://www.engineersgarage.com/contribution/controlling-mouse-pointer-using-python-script-and-accelerometer 119 | -------------------------------------------------------------------------------- /Surveillance Car Controlled via DTMF/README.md: -------------------------------------------------------------------------------- 1 | #Surveillance Car Controlled via DTMF 2 | 3 | ##Requirements: 4 | * DTMF decoder module 5 | * 3.5mm audio cable (for connecting mobile to DTMF module) 6 | * Arduino Uno 7 | * Chassis 8 | * Servo motor (7 kg/cm) 9 | * Android Phone(In my case Galaxy Ace Duos) 10 | * Laptop(can be desktop or any android device supporting multi windows) 11 | * Geared DC motors with Wheels 12 | * L298 motor driver module 13 | * Android apps [AirDroid], [DTMF Tone Generator], [VNC server] 14 | * Applications on laptop [VNC client] and [Browser] 15 | 16 | ##Summary: 17 | 18 | I made this project in order to build a surveillance car which can be controlled over Internet or on any private network. My objective was to **easily and cost effectively** do something that can be used for security purposes. 19 | 20 | My car uses uses DTMF module which takes it’s input from mobile phone attached to the car, that mobile is not only used to generate DTMF tones but also for the **surveillance by providing Live Footage from it’s camera**, over the network using [AirDroid]. 21 | 22 | Conventionally, any project using DTMF requires call from another cell phone to the one attached to the project, **which is not cost effective**, but in case of my project I used an android app [DTMF Tone Generator] which generates DTMF tone now for this to work I shared my phone’s screen over the network using [VNC server], **hence cost effective**. 23 | 24 | To make this Idea more effective I mounted the phone on a servo motor. This gave my Camera one degree of freedom, i.e. I can move it left and right without moving the bot. 25 | 26 | Generally, there is **one more security problem involved with DTMF** that I took care of was that anyone can control the bot by calling the mobile phone attached to the bot. A simple solution to this problem is to apply a PIN using DTMF tones. I demonstrated this concept in the video and for the inner working you can check the source code. 27 | 28 | Advantages: 29 | * Far much more cheaper than the bluetooth and Wifi modules, with almost Identical working. 30 | * Can be controlled via Internet using VPN. 31 | 32 | Utilities: 33 | * one can efficiently keep track on activities in his/her house when there are no occupants. 34 | * It can be used for surveillance purposes in Dangerous areas where there is any kind of threat to human life. 35 | 36 | 37 | 38 | ##Project's Video 39 | [https://www.youtube.com/watch?v=ecWZbtY6rOI] 40 | 41 | 42 | ##Project Images 43 | ![alt text][Image_1] 44 | ![alt text][Image_2] 45 | ![alt text][Image_3] 46 | 47 | ##Circuit Diagram: 48 | ![alt text][circuit diagram] 49 | 50 | ##Description: 51 | ###Explanation of circuit and hardware components: 52 | I used DTMF decoder module using MT8870DE and connected it to arduino as shown in circuit diagram. I pulled up pin13 permanently so as to provide +5v to the module. As can be seen D1-D4 are connected to pin12-pin9 respectively, here D1 represents least significant bit and D4 represents most significant bit. Pin8 of arduino is connected to STD pin of DTMF module, it becomes high whenever a new signal(valid tone) is given to module.
53 | Tones were generated via mobile phone and were fed as input to DTMF decoder module using 3.5mm audio jack. 54 | 55 | For motor driver I used L298D module here M11, M12 and M21, M22 are connection for LEFT and RIGHT motor respectively, when car is seen from back to front, when M11=M21=HIGH and M12=M22=LOW car will move forward. With this information you can easily use my source code directly by changing your connection respectively.
56 | PWM1 and PWM2 are the pins which can be used to control left and right motor's speed. I set both of them HIGH in order to attain maximum speed. EN1 and EN2 enables left and right motor when set high, so I shorted them with +5v supply from arduino.
57 | Vcc for DC motors was connected from a +12v supply. 58 | 59 | Phone was mounted on servo motor. Data pin of servo was connected to pin5 and +5v was taken from +5v supply and not from arduino as the current drawn by servo motor that I used exceeded the maximum current that could have been drawn from arduino.
60 | 61 | 62 | ###Explanation and working of peripheral applications used: 63 | First of all I connected my laptop and my mobile phone to the same network. 64 | 65 | I used [DTMF Tone Generator] to generate DTMF tones. This application was running on my mobile phone. 66 | 67 | Now in order share the display and gain control over my mobile phone from my laptop I created a VNC server by running [VNC server] application on my phone in background and using [VNC client] on my laptop, now I was able to view my mobile phone's screen and simulated touches from my laptop.
68 | At this point I was able to generate DTMF tones from my mobile phone using my laptop, therefore I was able to control my car using my laptop. 69 | 70 | To get the live feed from my phone's camera I used [AirDroid] application, which was running in background alongside [VNC server] and using any browser(preferably Chrome) on my laptop I was able to use the camera of my phone. 71 | 72 | Source code is well documented therefore all the required explanation is given as comments. 73 | 74 | 75 | 76 | ##Possible Modifications: 77 | * Instead of being on the same network one can control it via internet from any part of the world using VPN. 78 | * One can use any tablet or phone which supports multi window instead of laptop, as the only required application on my laptop were VNC client and a web browser both of them are available for android, ios, windows and Linux. 79 | * One can control the speed of vehicle by connecting PWM1 and PWM2 to pwm pins of arduino and by making necessary changes in source code. 80 | * If only maximum speed is required L293D can be used instead of L298, which might in turn save some bucks 81 | 82 | 83 | ##An extension of this project: 84 | I tethered wifi from the phone mounted on the vehicle, thereby creating a local network. Now I was able to control my vehicle without the need of an external router or internet. Although I wasn’t able to get the live feed as Airdroid need internet connection to initialize. 85 | 86 | Video: [https://www.youtube.com/watch?v=QwP7BD6L834] 87 | 88 | 89 | 90 | 91 | ##Published on Engineer's Garage 92 | [http://www.engineersgarage.com/contribution/surveillance-car-controlled-dtmf] 93 | 94 | 95 | [AirDroid]: https://play.google.com/store/apps/details?id=com.sand.airdroid&hl=en-GB 96 | [DTMF Tone Generator]: https://play.google.com/store/apps/details?id=com.amknott.ToneGen&hl=en-GB 97 | [VNC server]: https://play.google.com/store/apps/details?id=com.schumi.vncs&hl=en-GB 98 | [VNC client]: https://www.realvnc.com/ 99 | [Browser]: http://www.google.com/chrome/ 100 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/Surveillance%20Car%20Controlled%20via%20DTMF/circuit%20diagram.jpg "circuit diagram" 101 | 102 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/Surveillance%20Car%20Controlled%20via%20DTMF/Project_image001.jpg "Image_1" 103 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/Surveillance%20Car%20Controlled%20via%20DTMF/Project_image002.jpg "Image_2" 104 | [Image_3]: https://github.com/varun13169/Engineers_Garage/blob/master/Surveillance%20Car%20Controlled%20via%20DTMF/Project_image003.jpg "Image_3" 105 | 106 | [https://www.youtube.com/watch?v=ecWZbtY6rOI]: https://www.youtube.com/watch?v=ecWZbtY6rOI 107 | [https://www.youtube.com/watch?v=QwP7BD6L834]: https://www.youtube.com/watch?v=QwP7BD6L834 108 | 109 | [http://www.engineersgarage.com/contribution/surveillance-car-controlled-dtmf]: http://www.engineersgarage.com/contribution/surveillance-car-controlled-dtmf 110 | -------------------------------------------------------------------------------- /Adaptive Screen Brightness using LDR and Python Script/README.md: -------------------------------------------------------------------------------- 1 | #Adaptive Screen Brightness using LDR and Python script 2 | 3 | ##Requirements: 4 | * Arduino with Atmega328p 5 | * LDR 6 | * Python 2.7 on your machine 7 | * Python libraries: [pyserial] 8 | 9 | 10 | ##Summary: 11 | Every wondered how useful is the automatic brightness feature on phones, quickly adapting screen’s brightness according to the surrounding light intensity.
12 | In this project I try to create something similar for any PC or Laptop running on Linux(preferably Ubuntu 14.04).
13 | My goal was to keep it cheap and simple as much as possible.
14 | So to make a prototype of it I used LDR to measure light intensity and an arduino communicate with my machine. On my machine I used a python script to communicate over USB with arduino and to edit the file which is responsible for the brightness of screen.
15 | This project cost around Rs 300 just because of microcontroller that is being used(needless to say it’s a prototype).
16 | It has got very high utility specially for PC users.
17 | To get more detailed information on controlling brightness using terminal, you can checkout this [link].
18 | And to get more detailed references on atmega328p you can checkout [Atmega328p documentation].
19 | 20 | 21 | ##Project's Video: 22 | [https://www.youtube.com/watch?v=n7Pn08Q-GM8] 23 | 24 | ##Circuit Diagram: 25 | ![alt text][circuit diagram] 26 | 27 | 28 | ##Project Images 29 | ![alt text][Image_1] 30 | ![alt text][Image_2] 31 | 32 | 33 | ##Description: 34 | 35 | ###How I am uploading code into arduino 36 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
37 | Then, just type these three commands, in the same order, on your terminal / cmd. 38 | 39 | ```sh 40 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os main.c -o main.elf 41 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 42 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 43 | ``` 44 | 45 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 46 | 47 | 48 | ###Little bit about LDR that is being used 49 | LDR stands for Light Dependent Resistor. It’s resistance has an inverse relationship with luminous intensity, ie, its resistance tends to decrease with increase in light intensity. Generally, it has very high resistance somewhere around 1000 Kohms but when light falls on it, its resistance decreases dramatically to few hundred ohms.
50 | LDR is a very cheap device which finds its way in many of our day to day applications.
51 | 52 | ###Explaination of Source Code 53 | This program is an application of ADC and serial communication.
54 | I already did explain ADC [here], check it before reading this article.
55 | There are few changes that I made in setup_adc() function and ISR() block.
56 | In setup_adc() function I set the MUX1 bit in ADMUX register in order to start the conversion of value at PORTC2.
57 | 58 | In ISR() block, I first store 10-bit value from ADC in a variable(ldrValue). Then using conditional statements I map “ldrValue” to three levels of brightness:
59 | a. minimum_brightness = 500 60 | b. medium_brightness = 2500 61 | c. maximum_brightness = 4880 62 | *You might need to change them according to your machine.
63 | 64 | I’m using uartLibrary.h to send brightness value and ldr value to my laptop using serial communication. I build this library referring this [article]. After including this library I can use printf() function from stdio.h to send strings from atmega328p to my laptop.
65 | 66 | For detailed information please check the Source Code it’s very well documented.
67 | 68 | 69 | ###Explanation of Python Script 70 | I’m using [pyserial] libraries for serial communication, it’s freely available.
71 | Python script need root permission to run properly, else it will display an error message and exit.
72 | 73 | Once it gets the root permission it creates an object “ser” of “Serial” class and take two arguments in it:
74 | a. Serial Port: In my case it is '/dev/ttyUSB0' 75 | b. Baud rate: I my case it is 9600 76 | then, it sets the file path in a variable(path).
77 | *You might need to edit them according to your machine.
78 | 79 | Then in an infinite loop I put a try & except block Just to take care of initial garbage values.
80 | In try block, a variable(value) stores the list of two strings one is the brightness value other is the ldr value.
81 | After that it opens the file given in “path” variable in write mode and writes the brightness value in it, then it saves and close the file.
82 | And for debugging purpose, it prints the list with brightness and ldr value.
83 | 84 | For more information, you can also check this link on [changing brightness through terminal].
85 | 86 | 87 | ###Explanation of Circuit 88 | Circuit is fairly simple, as can be seen in image and circuit diagram, I build a potential divider using a 330 ohm resistor and LDR.
89 | One terminal of LDR is connected to PORTC1 and other to PORTC2, PORTC1 is pulled up to provide Vcc, similar thing is done with resistor, one terminal is connected to PORTC2 and other one to PORTC3, PORTC3 is pulled down to provide Gnd.
90 | Analog values are read at PORTC2, which is the junction of resistor and LDR.
91 | 92 | 93 | ###Getting started with this Project: 94 | There are three files: 95 | 1. main.c contains the source code for atmega328p side of this application. 96 | 2. uartLibrary.h contains definition of all the functions necessary for serial communication 97 | 3. python_serial.py it reads data from serial port and controls the mouse pointer 98 | 99 | Make nesseary changes in main.c and python_serial.py according to your machine and LDR. 100 | Place main.c and uartLibrary.h in same directory, and upload the code to atmega328p.
101 | Now, run the python script with root permission and BAAMMM!! you are ready to go. Just cover LDR with your hand and brightness of your screen will decrease or put a flashlight on LDR and brightness will increase.
102 | 103 | 104 | ##Published on Engineer's Garage 105 | [http://www.engineersgarage.com/contribution/adaptive-screen-brightness-using-ldr-and-python-script] 106 | 107 | 108 | [pyserial]: http://pyserial.sourceforge.net/ 109 | [link]: http://askubuntu.com/questions/56155/how-can-i-change-brightness-through-terminal 110 | [Atmega328p documentation]: http://www.atmel.com/Images/doc8161.pdf 111 | 112 | [https://www.youtube.com/watch?v=n7Pn08Q-GM8]: https://www.youtube.com/watch?v=n7Pn08Q-GM8 113 | 114 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/Adaptive%20Screen%20Brightness%20using%20LDR%20and%20Python%20Script/cicuit%20diagram.jpg 115 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/Adaptive%20Screen%20Brightness%20using%20LDR%20and%20Python%20Script/Project_image001.jpg 116 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/Adaptive%20Screen%20Brightness%20using%20LDR%20and%20Python%20Script/Project_image002.jpg 117 | 118 | 119 | [here]: https://github.com/varun13169/Engineers_Garage/tree/master/ADC%20in%20Atmega328p 120 | [article]: http://www.appelsiini.net/2011/simple-usart-with-avr-libc 121 | [changing brightness through terminal]: http://askubuntu.com/questions/56155/how-can-i-change-brightness-through-terminal 122 | [http://www.engineersgarage.com/contribution/adaptive-screen-brightness-using-ldr-and-python-script]: http://www.engineersgarage.com/contribution/adaptive-screen-brightness-using-ldr-and-python-script 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /Swapping Workspace in Ubuntu using Accelerometer and Python Script/README.md: -------------------------------------------------------------------------------- 1 | #Swapping Workspace in Ubuntu using Accelerometer and Python Script 2 | 3 | ##Requirements: 4 | * Arduino with Atmega328p
5 | * Accelerometer ADXL335
6 | * Ubuntu 14.04 and Python 2.7 on your machine
7 | * Python libraries [Pyserial], subprocess and sys
8 | * Wmctrl installed on your ubuntu, use ”sudo apt-get install wmctrl”
9 | 10 | ##Summary: 11 | In this project I’ll demonstrate swapping of workspace in ubuntu using accelerometer and python script. I am using [wmctrl] command that will take arguments according to the accelerometer values.
12 | On hardware level this project is similar to [Controlling Mouse Pointer using Python Script and Accelerometer].
13 | Python libraries that are being used are [Pyserial], subprocess and sys. Pyserial is used to communicate between arduino and my machine. Subprocess is used to execute bash commands in python script and sys is used to exit program using try and except block.
14 | [Pyserial] is a freely available non-standard library that is easy to install, just like any non-standard library. 15 | Accelerometer that I’m using is ADXL335, it’s a triple axis accelerometer.
16 | 17 | 18 | ##Project's Video: 19 | [https://www.youtube.com/watch?v=Et3rpa4WQI8] 20 | 21 | ##Circuit Diagram: 22 | ![alt text][circuit diagram] 23 | 24 | 25 | ##Project Images 26 | ![alt text][Image_1] 27 | ![alt text][Image_2] 28 | ![alt text][Image_3] 29 | 30 | 31 | ##Description: 32 | 33 | ###How I am uploading code into arduino: 34 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
35 | Then, just type these three commands, in the same order, on your terminal / cmd. 36 | 37 | ```sh 38 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os main.c -o main.elf 39 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 40 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 41 | ``` 42 | 43 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 44 | 45 | 46 | ###Little bit about accelerometer being used: 47 | I’m using adxl335 it’s a triple axis accelerometer. It can measure acceleration with a minimum full scale range of +-3g. It can used to measure tilt by measuring static acceleration of gravity or it can measure impact from shock and vibration by measuring dynamic acceleration.
48 | For more details and knowledge you can always look up adxl335 [datasheet].
49 | 50 | ###Explanation of Source Code: 51 | 52 | This program is an application of ADC and serial communication.
53 | I already did explain ADC [here], check it before reading this article.
54 | There are few changes that I made in setup_adc() function and ISR() block.
55 | 56 | In setup_adc() function I set the MUX1 bit in ADMUX register in order to start the conversion of value at PORTC2.
57 | In ISR() block, I first store 10-bit value from ADC in a variable. Then check four bits in ADMUX, starting from LSB, depending on these four bits I decide whether 10-bit value is for x,y,z axis.
58 | Then I set last four bits in ADMUX for next conversion.
59 | 60 | After that a workspace() function is called.
61 | It takes no argument but uses two globally defined variables viz. xRaw and yRaw.
62 | As I’m using four workspaces, so the values of xRaw and yRaw will decide whether to swap to workspace1, workspace2, workspace3 or workspace4.
63 | 64 | I’m using uartLibrary.h to send readings from accelerometer to my laptop using serial communication. I build this library referring this [article] . After including this library I can use printf() function from stdio.h to send strings from Atmega358p to my laptop.
65 | 66 | For detailed information please check the Source Code it’s very well documented.
67 | 68 | 69 | 70 | ###Explanation of Python Script: 71 | I’m using three libraries [Pyserial], subprocess and sys. Only [Pyserial] is the one that is not preinstalled with python2.7 but its freely available and very easy to install.
72 | First I created an object “ser” of “Serial” class and gave two arguments in it
73 | 1. Serial Port: In my case it is '/dev/ttyUSB1'
74 | 2. Baud rate: I my case it’s 9600
75 | 76 | Then I created a try and except block to check whether [wmctrl] is installed on your machine or not. If not it will display the warning and exit the program.
77 | Then in an infinite loop I put a try & except block because initially trash values are send from atmega328p.
78 | In try block I read data that is being send over serial port then break it and convert it to integer and store it in a list. Then save the command in a variable(bashCommand) accordingly.
79 | Then command which is stored in that variable(bashCommand) is executed.
80 | Then I print these values on terminal for debugging purposes.
81 | For detailed information please check the Python Script it’s well documented.
82 | 83 | 84 | ###Explanation of Circuit: 85 | As can be seen in images, my accelerometer module don't have a header pin for ST, and all other i/o pins are in straight line. So instead of using a breadboard for connections I simply placed accelerometer on Analog pins of Arduino which maps to PORTC on atmega328p.
86 | For Vcc and GND I declared PORTC1 and PORTC5 as output and pulled down PORTC1 for GND, pulled up PORTC5 for Vcc.
87 | Now I can simply measure acceleration from x,y,z axis on PORTC2,3,4 respectively.
88 | 89 | 90 | 91 | 92 | ##Getting started with this Project 93 | There are three files:
94 | 1. main.c contains the source code for atmega328p side of this application.
95 | 2. uartLibrary.h contains definition of all the functions necessary for serial communication.
96 | 3. python_serial.py it reads data from serial port and controls the mouse pointer.
97 | 98 | Place main.c and uartLibrary.h in same directory, and upload the code to atmega328p.
99 | Now, run the python script and BAAMMM!! you are ready to go. Just move accelerometer and accordingly your workspace will swap.
100 | 101 | 102 | 103 | 104 | ##Published on Engineer's Garage 105 | [http://www.engineersgarage.com/contribution/swapping-workspace-ubuntu-using-accelerometer-and-python-script] 106 | 107 | [Pyserial]: http://pyserial.sourceforge.net/ 108 | [datasheet]: https://www.sparkfun.com/datasheets/Components/SMD/adxl335.pdf 109 | [Controlling Mouse Pointer using Python Script and Accelerometer]: https://github.com/varun13169/Engineers_Garage/tree/master/Controlling%20Mouse%20Pointer%20using%20Python%20Script%20and%20Accelerometer 110 | [here]: https://github.com/varun13169/Engineers_Garage/tree/master/ADC%20in%20Atmega328p 111 | [article]: http://www.appelsiini.net/2011/simple-usart-with-avr-libc 112 | 113 | [wmctrl]: http://askubuntu.com/questions/41093/is-there-a-command-to-go-a-specific-workspace 114 | 115 | [https://www.youtube.com/watch?v=Et3rpa4WQI8]: https://www.youtube.com/watch?v=Et3rpa4WQI8 116 | 117 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/Swapping%20Workspace%20in%20Ubuntu%20using%20Accelerometer%20and%20Python%20Script/circuit%20diagram.jpg "circuit diagram" 118 | 119 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/Swapping%20Workspace%20in%20Ubuntu%20using%20Accelerometer%20and%20Python%20Script/Project_image001.jpg "Image_1" 120 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/Swapping%20Workspace%20in%20Ubuntu%20using%20Accelerometer%20and%20Python%20Script/Project_image002.jpg "Image_2" 121 | [Image_3]: https://github.com/varun13169/Engineers_Garage/blob/master/Swapping%20Workspace%20in%20Ubuntu%20using%20Accelerometer%20and%20Python%20Script/Project_image003.jpg "Image_3" 122 | 123 | [avr­libc]: http://www.nongnu.org/avr-libc/ 124 | [winAVR]: https://sourceforge.net/projects/winavr/ 125 | 126 | [http://www.engineersgarage.com/contribution/swapping-workspace-ubuntu-using-accelerometer-and-python-script]: http://www.engineersgarage.com/contribution/swapping-workspace-ubuntu-using-accelerometer-and-python-script 127 | -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /README.md: -------------------------------------------------------------------------------- 1 | #Reaction Time Game using External and Pin Change Interrupts in Atmega328p 2 | 3 | ##Requirements: 4 | * Arduino with Atmega328p 5 | * Jumper wires 6 | * Bread Board 7 | * Push Buttons 8 | * 1k Resistors 9 | * LEDs 10 | 11 | 12 | ##Summary: 13 | This game test reaction time of two players, and declare the fastest one as winner. To do this I am using external interrupts and pin change interrupts in atmega328p. It gives four chance to each play, time of each chance is summed up and then player with minimum time is declared as the winner.
14 | For the demo purpose, I’ll be using pseudo random function in it, just to keep track.
15 | This game has precision of 1ms and accuracy of about +/- 4ms.
16 | It also displays the concept of debouncing.
17 | This game’s main motive is to show the beauty of external interrupts over polling and to show the how to reduce debouncing effect using software modifications.
18 | 19 | 20 | ##What my project is about: 21 | My project is inspired from fastest finger first game.
22 | In which there are two players and both get four chances and reaction time of all four chances are summed up, one who have the minimum reaction time wins the game.
23 | 24 | Game starts with the display on LCD which reads “Reaction Time Game” and then “Push Button To Start”.
25 | When the push button is pressed, game starts in 3.5secs.
26 | Then one out of four LED glows Player1 is expected to press corresponding button to that LED, time is recorded for the same, if Player1 presses another button that does not correspond to that specific LED than a penalty of 1000ms is imposed along with the recorded time.
27 | Score after each turn is displayed on LCD and this thing is repeated for four times.
28 | After that Player2 begins and same thing is repeated.
29 | Then score of both the players are compared and fastest one is declared winner.
30 | After around two seconds latter “Push Button To Play Again” is displayed on LCD.
31 | 32 | 33 | ##Project's Video: 34 | [https://www.youtube.com/watch?v=fMYVjDvXV7Y] 35 | 36 | 37 | ##Circuit Diagram: 38 | ![alt text][circuit diagram] 39 | 40 | 41 | ##Project Images 42 | ![alt text][Image_1] 43 | ![alt text][Image_2] 44 | 45 | 46 | 47 | 48 | 49 | ##Description: 50 | 51 | 52 | ###How I am uploading code into arduino 53 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
54 | Then, just type these three commands, in the same order, on your terminal / cmd. 55 | 56 | ```sh 57 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os lcd.c main.c -o main.elf 58 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 59 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 60 | ``` 61 | 62 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 63 | 64 | ###What are External Interrupts: 65 | External interrupts are very useful to interact with physical world, because of its unpredictable nature.
66 | There are two ways of sensing data from different pins, one is polling other is using interrupts. Both polling and interrupts have pros and cons associated with them.
67 | In polling you check status of each and every pin in a sequential manner:
68 | pros:
69 | 1) Everyone one gets a fair chance
70 | cons:
71 | 1) Inefficient, can’t do some other activity in between, specially have to go and check
72 | 2) Loss of data might occur in an unpredictable scenario.
73 | 74 | Whereas, in interrupts you let your microcontroller do some other important stuff and whenever an interrupt is generated you stop the normal working of microcontroller and change its behavior accordingly.
75 | pros:
76 | 1) Efficient, can do some other work in between
77 | 2) No loss of data
78 | cons:
79 | 1) Extra resources on hardware level are required
80 |
81 |
82 | 83 | 84 | ###Little bit of description about registers that are being used: 85 | ![alt text][reg1] 86 | * Bit 7..4 – Res: Reserved Bits
87 | These bits are unused bits in the ATmega48PA/88PA/168PA/328P, and will always read as zero.
88 | * Bit 3, 2 – ISC11, ISC10: Interrupt Sense Control 1 Bit 1 and Bit 0
89 | Used for Interrupt 1 Sense Control, check the table below
90 | * Bit 1, 0 – ISC01, ISC00: Interrupt Sense Control 0 Bit 1 and Bit 0
91 | Used for Interrupt 0 Sense Control, check the table below
92 | 93 | ![alt text][reg2] 94 | * Bit 7:2 – Reserved
95 | These bits are unused bits in the ATmega48A/PA/88A/PA/168A/PA/328/P, and will always read as zero.
96 | * Bit 1 – INT1: External Interrupt Request 1 Enable
97 | When the INT1 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), the external pin interrupt is enabled.
98 | * Bit 0 – INT0: External Interrupt Request 0 Enable
99 | When the INT0 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), the external pin interrupt is enabled.
100 | 101 | ![alt text][reg3] 102 | * Bit 7:3 – Reserved
103 | These bits are unused bits in the ATmega48A/PA/88A/PA/168A/PA/328/P, and will always read as zero.
104 | * Bit 2 – PCIE2: Pin Change Interrupt Enable 2
105 | When the PCIE2 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt 2 is enabled. Any change on any enabled PCINT[23:16] pin will cause an interrupt.
106 | * Bit 1 – PCIE1: Pin Change Interrupt Enable 1
107 | When the PCIE1 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt 1 is enabled. Any change on any enabled PCINT[14:8] pin will cause an interrupt.
108 | * Bit 0 – PCIE0: Pin Change Interrupt Enable 0
109 | When the PCIE0 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt 0 is enabled. Any change on any enabled PCINT[7:0] pin will cause an interrupt.
110 | 111 | ![alt text][reg4] 112 | * Bit 7 – Reserved
113 | This bit is an unused bit in the ATmega48A/PA/88A/PA/168A/PA/328/P, and will always read as zero.
114 | * Bit 6:0 – PCINT[14:8]: Pin Change Enable Mask 14...8
115 | Each PCINT[14:8]-bit selects whether pin change interrupt is enabled on the corresponding I/O pin. If PCINT[14:8] is set and the PCIE1 bit in PCICR is set, pin change interrupt is enabled on the corresponding I/O pin. If PCINT[14:8] is cleared, pin change interrupt on the corresponding I/O pin is disabled.
116 |
117 |
118 | 119 | 120 | ##Published on Engineer's Garage 121 | [http://www.engineersgarage.com/contribution/external-and-pin-change-interrupts-atmega328p-reaction-time-game] 122 | 123 | 124 | 125 | 126 | 127 | [https://www.youtube.com/watch?v=fMYVjDvXV7Y]: https://www.youtube.com/watch?v=fMYVjDvXV7Y 128 | 129 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/circuit%20diagram.jpg "circuit diagram" 130 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/Project_image001.jpg "Image_1" 131 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/Project_image002.jpg "Image_2" 132 | 133 | [reg1]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/Reg1.png 134 | [reg2]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/Reg2.png 135 | [reg3]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/Reg3.png 136 | [reg4]: https://github.com/varun13169/Engineers_Garage/blob/master/External%20and%20Pin%20Change%20Interrupts%20in%20Atmega328p:%20Reaction%20Time%20Game/Reg4.png 137 | 138 | [avr­libc]: http://www.nongnu.org/avr-libc/ 139 | [winAVR]: https://sourceforge.net/projects/winavr/ 140 | 141 | [http://www.engineersgarage.com/contribution/external-and-pin-change-interrupts-atmega328p-reaction-time-game]: http://www.engineersgarage.com/contribution/external-and-pin-change-interrupts-atmega328p-reaction-time-game 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /lcd.c: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "lcd.h" 7 | //D4-D7 connected to D4-D7 8 | 9 | #define rs PB0 //pin8 10 | #define en PB1 //pin9 11 | 12 | 13 | 14 | int base_address[8]={64,72,80,88,96,104,112,120}; 15 | 16 | void start() 17 | { 18 | command(0x28); // To initialize LCD in 2 lines, 5X8 dots and 4bit mode. 19 | command(0x0C); // Display ON cursor OFF. E for cursor ON and C for cursor OFF 20 | command(0x06); // Entry mode-increment cursor by 1 21 | command(0x01); // Clear screen 22 | command(0x80); // Sets cursor to (0,0) 23 | } 24 | 25 | 26 | 27 | 28 | void command(char LcdCommand) // Basic function used in giving command 29 | { // to LCD 30 | char UpperHalf, LowerHalf; 31 | 32 | UpperHalf = LcdCommand & 0xF0; // upper 4 bits of command 33 | PORTD &= 0x0F; // flushes upper half of PortD to 0, but retains lower half of PortD 34 | PORTD |= UpperHalf; 35 | PORTB &= ~(1< 0) // less than 16, after 16th character 80 | { // everything will be ignored. 81 | data(*StringOfCharacters++); 82 | } 83 | } 84 | 85 | 86 | void cut(char *str) // It's a souped up version of Send_A_String 87 | { // It takes a string, if number of characters 88 | int i=0; // is greater than 16, it moves the cursor to 89 | if(strlen(str)<16) // next line and starts printing there 90 | {Send_A_String(str);} // 91 | // It has its own limitations, maximum number 92 | else // of character is 32, after 32nd character 93 | { // it'll ignore the rest. 94 | while(i<16) 95 | { 96 | data(str[i]); 97 | i=i+1; 98 | } 99 | command(0xC0); 100 | while(str[i]!='\0' && i<32) 101 | { 102 | data(str[i]); 103 | i=i+1; 104 | } 105 | 106 | } 107 | } 108 | 109 | 110 | void Send_An_Integer(int x) // Takes an integer as input and displays it 111 | { // value of integer should be in between 112 | char buffer[8]; // the range of "int", 113 | itoa(x,buffer,10); // else it'll print garbage values. 114 | Send_A_String(buffer); // It use Send_A_String() for displaying. 115 | } 116 | 117 | 118 | 119 | void setCursor(int row,int column) // Indexing starts from 0. 120 | { // Therefore, 121 | switch(row) // 0<=row<=1 and 0<=column<=15. 122 | { // 123 | case 0: // If arguments are outside the 124 | switch(column) // the specified range, then function 125 | { // will not work and ignore the values 126 | case 0: 127 | command(0x80);break; 128 | case 1: 129 | command(0x81);break; 130 | case 2: 131 | command(0x82);break; 132 | case 3: 133 | command(0x83);break; 134 | case 4: 135 | command(0x84);break; 136 | case 5: 137 | command(0x85);break; 138 | case 6: 139 | command(0x86);break; 140 | case 7: 141 | command(0x87);break; 142 | case 8: 143 | command(0x88);break; 144 | case 9: 145 | command(0x89);break; 146 | case 10: 147 | command(0x8A);break; 148 | case 11: 149 | command(0x8B);break; 150 | case 12: 151 | command(0x8C);break; 152 | case 13: 153 | command(0x8D);break; 154 | case 14: 155 | command(0x8E);break; 156 | case 15: 157 | command(0x8F);break; 158 | default: 159 | break; 160 | } 161 | break; 162 | case 1: 163 | switch(column) 164 | { 165 | case 0: 166 | command(0xC0);break; 167 | case 1: 168 | command(0xC1);break; 169 | case 2: 170 | command(0xC2);break; 171 | case 3: 172 | command(0xC3);break; 173 | case 4: 174 | command(0xC4);break; 175 | case 5: 176 | command(0xC5);break; 177 | case 6: 178 | command(0xC6);break; 179 | case 7: 180 | command(0xC7);break; 181 | case 8: 182 | command(0xC8);break; 183 | case 9: 184 | command(0xC9);break; 185 | case 10: 186 | command(0xCA);break; 187 | case 11: 188 | command(0xCB);break; 189 | case 12: 190 | command(0xCC);break; 191 | case 13: 192 | command(0xCD);break; 193 | case 14: 194 | command(0xCE);break; 195 | case 15: 196 | command(0xCF);break; 197 | default: 198 | break; 199 | } 200 | break; 201 | default: 202 | break; 203 | } 204 | 205 | } 206 | 207 | 208 | 209 | 210 | void clearScreen() // Clears the screen and 211 | { // returns cursor to (0,0) position 212 | command(0x01); 213 | } 214 | void home() // Returns cursor to (0,0) position 215 | { 216 | command(0x02); 217 | } 218 | 219 | 220 | 221 | void cursor() // Shows cursor as an underscore 222 | { 223 | command(0x0E); 224 | } 225 | void noCursor() // Hides the cursor 226 | { 227 | command(0x0C); 228 | } 229 | 230 | 231 | 232 | void blink() // Shows cursor as a blinking black spot 233 | { 234 | command(0x0F); 235 | } 236 | void noBlink() // Hides the cursor 237 | { 238 | command(0x0C); 239 | } 240 | 241 | 242 | 243 | void display() // Display ON with Cursor OFF 244 | { 245 | command(0x0C); 246 | } 247 | void noDisplay() // Display OFF 248 | { 249 | command(0x08); 250 | } 251 | 252 | 253 | 254 | void scrollDisplayLeft() // Scrolls the contents of the 255 | { // display(text and cursor) one space to the left 256 | command(0x18); 257 | } 258 | void scrollDisplayRight() // Scrolls the contents of the 259 | { // display(text and cursor) one space to the right 260 | command(0x1C); 261 | } 262 | 263 | 264 | 265 | void autoscroll() // This causes each character output to the display to push previous 266 | { // characters over by one space in right to left direction 267 | command(0x07); 268 | } 269 | void noAutoscroll() // Turns off automatic scrolling of the LCD. 270 | { 271 | command(0x06); 272 | } 273 | 274 | 275 | 276 | 277 | void createChar(int num,unsigned int *charArray)// Takes input two arguments 278 | { // 1st is a number between 0-7, 279 | int i=0; // which maps to eight base address 280 | command(base_address[num]); // 2nd is an array of 8 integers, 281 | while(i<8) // each integer is formed by 5 bits 282 | { // which determine the pixels in the 283 | data(charArray[i]); // row same as the index of that integer 284 | i++; // 285 | } // Before printing the character, one must 286 | } // set cursor else cursor won't get printed. 287 | // To print Created Character, one can use data() function. 288 | // Just pass a number between 0-7 as an argument in data() function. 289 | // 290 | // Example: To print value stored at zero 291 | // data(0); CORRECT 292 | // data('0'); INCORRECT 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | -------------------------------------------------------------------------------- /Threading and Timers in Atmega328p/lcd.c: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "lcd.h" 7 | //D4-D7 connected to D4-D7 8 | 9 | #define rs PB0 //pin8 10 | #define en PB1 //pin9 11 | 12 | 13 | 14 | int base_address[8]={64,72,80,88,96,104,112,120}; 15 | 16 | void start() 17 | { 18 | DDRB = 0x03; // PB0 and PB1 declared as output 19 | DDRD = 0xF0; // PD4,PD5,PD6,PD7 declared as output 20 | command(0x28); // To initialize LCD in 2 lines, 5X8 dots and 4bit mode. 21 | command(0x0C); // Display ON cursor OFF. E for cursor ON and C for cursor OFF 22 | command(0x06); // Entry mode-increment cursor by 1 23 | command(0x01); // Clear screen 24 | command(0x80); // Sets cursor to (0,0) 25 | } 26 | 27 | 28 | 29 | 30 | void command(char LcdCommand) // Basic function used in giving command 31 | { // to LCD 32 | char UpperHalf, LowerHalf; 33 | 34 | UpperHalf = LcdCommand & 0xF0; // upper 4 bits of command 35 | PORTD &= 0x0F; // flushes upper half of PortD to 0, but retains lower half of PortD 36 | PORTD |= UpperHalf; 37 | PORTB &= ~(1< 0) // less than 16, after 16th character 82 | { // everything will be ignored. 83 | data(*StringOfCharacters++); 84 | } 85 | } 86 | 87 | 88 | void cut(char *str) // It's a souped up version of Send_A_String 89 | { // It takes a string, if number of characters 90 | int i=0; // is greater than 16, it moves the cursor to 91 | if(strlen(str)<16) // next line and starts printing there 92 | {Send_A_String(str);} // 93 | // It has its own limitations, maximum number 94 | else // of character is 32, after 32nd character 95 | { // it'll ignore the rest. 96 | while(i<16) 97 | { 98 | data(str[i]); 99 | i=i+1; 100 | } 101 | command(0xC0); 102 | while(str[i]!='\0' && i<32) 103 | { 104 | data(str[i]); 105 | i=i+1; 106 | } 107 | 108 | } 109 | } 110 | 111 | 112 | void Send_An_Integer(int x) // Takes an integer as input and displays it 113 | { // value of integer should be in between 114 | char buffer[8]; // the range of "int", 115 | itoa(x,buffer,10); // else it'll print garbage values. 116 | Send_A_String(buffer); // It use Send_A_String() for displaying. 117 | } 118 | 119 | 120 | 121 | void setCursor(int row,int column) // Indexing starts from 0. 122 | { // Therefore, 123 | switch(row) // 0<=row<=1 and 0<=column<=15. 124 | { // 125 | case 0: // If arguments are outside the 126 | switch(column) // the specified range, then function 127 | { // will not work and ignore the values 128 | case 0: 129 | command(0x80);break; 130 | case 1: 131 | command(0x81);break; 132 | case 2: 133 | command(0x82);break; 134 | case 3: 135 | command(0x83);break; 136 | case 4: 137 | command(0x84);break; 138 | case 5: 139 | command(0x85);break; 140 | case 6: 141 | command(0x86);break; 142 | case 7: 143 | command(0x87);break; 144 | case 8: 145 | command(0x88);break; 146 | case 9: 147 | command(0x89);break; 148 | case 10: 149 | command(0x8A);break; 150 | case 11: 151 | command(0x8B);break; 152 | case 12: 153 | command(0x8C);break; 154 | case 13: 155 | command(0x8D);break; 156 | case 14: 157 | command(0x8E);break; 158 | case 15: 159 | command(0x8F);break; 160 | default: 161 | break; 162 | } 163 | break; 164 | case 1: 165 | switch(column) 166 | { 167 | case 0: 168 | command(0xC0);break; 169 | case 1: 170 | command(0xC1);break; 171 | case 2: 172 | command(0xC2);break; 173 | case 3: 174 | command(0xC3);break; 175 | case 4: 176 | command(0xC4);break; 177 | case 5: 178 | command(0xC5);break; 179 | case 6: 180 | command(0xC6);break; 181 | case 7: 182 | command(0xC7);break; 183 | case 8: 184 | command(0xC8);break; 185 | case 9: 186 | command(0xC9);break; 187 | case 10: 188 | command(0xCA);break; 189 | case 11: 190 | command(0xCB);break; 191 | case 12: 192 | command(0xCC);break; 193 | case 13: 194 | command(0xCD);break; 195 | case 14: 196 | command(0xCE);break; 197 | case 15: 198 | command(0xCF);break; 199 | default: 200 | break; 201 | } 202 | break; 203 | default: 204 | break; 205 | } 206 | 207 | } 208 | 209 | 210 | 211 | 212 | void clearScreen() // Clears the screen and 213 | { // returns cursor to (0,0) position 214 | command(0x01); 215 | } 216 | void home() // Returns cursor to (0,0) position 217 | { 218 | command(0x02); 219 | } 220 | 221 | 222 | 223 | void cursor() // Shows cursor as an underscore 224 | { 225 | command(0x0E); 226 | } 227 | void noCursor() // Hides the cursor 228 | { 229 | command(0x0C); 230 | } 231 | 232 | 233 | 234 | void blink() // Shows cursor as a blinking black spot 235 | { 236 | command(0x0F); 237 | } 238 | void noBlink() // Hides the cursor 239 | { 240 | command(0x0C); 241 | } 242 | 243 | 244 | 245 | void display() // Display ON with Cursor OFF 246 | { 247 | command(0x0C); 248 | } 249 | void noDisplay() // Display OFF 250 | { 251 | command(0x08); 252 | } 253 | 254 | 255 | 256 | void scrollDisplayLeft() // Scrolls the contents of the 257 | { // display(text and cursor) one space to the left 258 | command(0x18); 259 | } 260 | void scrollDisplayRight() // Scrolls the contents of the 261 | { // display(text and cursor) one space to the right 262 | command(0x1C); 263 | } 264 | 265 | 266 | 267 | void autoscroll() // This causes each character output to the display to push previous 268 | { // characters over by one space in right to left direction 269 | command(0x07); 270 | } 271 | void noAutoscroll() // Turns off automatic scrolling of the LCD. 272 | { 273 | command(0x06); 274 | } 275 | 276 | 277 | 278 | 279 | void createChar(int num,unsigned int *charArray)// Takes input two arguments 280 | { // 1st is a number between 0-7, 281 | int i=0; // which maps to eight base address 282 | command(base_address[num]); // 2nd is an array of 8 integers, 283 | while(i<8) // each integer is formed by 5 bits 284 | { // which determine the pixels in the 285 | data(charArray[i]); // row same as the index of that integer 286 | i++; // 287 | } // Before printing the character, one must 288 | } // set cursor else cursor won't get printed. 289 | // To print Created Character, one can use data() function. 290 | // Just pass a number between 0-7 as an argument in data() function. 291 | // 292 | // Example: To print value stored at zero 293 | // data(0); CORRECT 294 | // data('0'); INCORRECT 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /AVR(atmega328p) Library for LCD JHD162A/lcd.c: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "lcd.h" 7 | //D4-D7 connected to D4-D7 8 | 9 | #define rs PB0 //pin8 10 | #define en PB1 //pin9 11 | 12 | 13 | 14 | int base_address[8]={64,72,80,88,96,104,112,120}; 15 | 16 | void start() 17 | { 18 | DDRB = 0x03; // PB0 and PB1 declared as output 19 | DDRD = 0xF0; // PD4,PD5,PD6,PD7 declared as output 20 | command(0x28); // To initialize LCD in 2 lines, 5X8 dots and 4bit mode. 21 | command(0x0C); // Display ON cursor OFF. E for cursor ON and C for cursor OFF 22 | command(0x06); // Entry mode-increment cursor by 1 23 | command(0x01); // Clear screen 24 | command(0x80); // Sets cursor to (0,0) 25 | } 26 | 27 | 28 | 29 | 30 | void command(char LcdCommand) // Basic function used in giving command 31 | { // to LCD 32 | char UpperHalf, LowerHalf; 33 | 34 | UpperHalf = LcdCommand & 0xF0; // upper 4 bits of command 35 | PORTD &= 0x0F; // flushes upper half of PortD to 0, but retains lower half of PortD 36 | PORTD |= UpperHalf; 37 | PORTB &= ~(1< 0) // less than 16, after 16th character 82 | { // everything will be ignored. 83 | data(*StringOfCharacters++); 84 | } 85 | } 86 | 87 | 88 | void cut(char *str) // It's a souped up version of Send_A_String 89 | { // It takes a string, if number of characters 90 | int i=0; // is greater than 16, it moves the cursor to 91 | if(strlen(str)<16) // next line and starts printing there 92 | {Send_A_String(str);} // 93 | // It has its own limitations, maximum number 94 | else // of character is 32, after 32nd character 95 | { // it'll ignore the rest. 96 | while(i<16) 97 | { 98 | data(str[i]); 99 | i=i+1; 100 | } 101 | command(0xC0); 102 | while(str[i]!='\0' && i<32) 103 | { 104 | data(str[i]); 105 | i=i+1; 106 | } 107 | 108 | } 109 | } 110 | 111 | 112 | void Send_An_Integer(int x) // Takes an integer as input and displays it 113 | { // value of integer should be in between 114 | char buffer[8]; // the range of "int", 115 | itoa(x,buffer,10); // else it'll print garbage values. 116 | Send_A_String(buffer); // It use Send_A_String() for displaying. 117 | } 118 | 119 | 120 | 121 | void setCursor(int row,int column) // Indexing starts from 0. 122 | { // Therefore, 123 | switch(row) // 0<=row<=1 and 0<=column<=15. 124 | { // 125 | case 0: // If arguments are outside the 126 | switch(column) // the specified range, then function 127 | { // will not work and ignore the values 128 | case 0: 129 | command(0x80);break; 130 | case 1: 131 | command(0x81);break; 132 | case 2: 133 | command(0x82);break; 134 | case 3: 135 | command(0x83);break; 136 | case 4: 137 | command(0x84);break; 138 | case 5: 139 | command(0x85);break; 140 | case 6: 141 | command(0x86);break; 142 | case 7: 143 | command(0x87);break; 144 | case 8: 145 | command(0x88);break; 146 | case 9: 147 | command(0x89);break; 148 | case 10: 149 | command(0x8A);break; 150 | case 11: 151 | command(0x8B);break; 152 | case 12: 153 | command(0x8C);break; 154 | case 13: 155 | command(0x8D);break; 156 | case 14: 157 | command(0x8E);break; 158 | case 15: 159 | command(0x8F);break; 160 | default: 161 | break; 162 | } 163 | break; 164 | case 1: 165 | switch(column) 166 | { 167 | case 0: 168 | command(0xC0);break; 169 | case 1: 170 | command(0xC1);break; 171 | case 2: 172 | command(0xC2);break; 173 | case 3: 174 | command(0xC3);break; 175 | case 4: 176 | command(0xC4);break; 177 | case 5: 178 | command(0xC5);break; 179 | case 6: 180 | command(0xC6);break; 181 | case 7: 182 | command(0xC7);break; 183 | case 8: 184 | command(0xC8);break; 185 | case 9: 186 | command(0xC9);break; 187 | case 10: 188 | command(0xCA);break; 189 | case 11: 190 | command(0xCB);break; 191 | case 12: 192 | command(0xCC);break; 193 | case 13: 194 | command(0xCD);break; 195 | case 14: 196 | command(0xCE);break; 197 | case 15: 198 | command(0xCF);break; 199 | default: 200 | break; 201 | } 202 | break; 203 | default: 204 | break; 205 | } 206 | 207 | } 208 | 209 | 210 | 211 | 212 | void clearScreen() // Clears the screen and 213 | { // returns cursor to (0,0) position 214 | command(0x01); 215 | } 216 | void home() // Returns cursor to (0,0) position 217 | { 218 | command(0x02); 219 | } 220 | 221 | 222 | 223 | void cursor() // Shows cursor as an underscore 224 | { 225 | command(0x0E); 226 | } 227 | void noCursor() // Hides the cursor 228 | { 229 | command(0x0C); 230 | } 231 | 232 | 233 | 234 | void blink() // Shows cursor as a blinking black spot 235 | { 236 | command(0x0F); 237 | } 238 | void noBlink() // Hides the cursor 239 | { 240 | command(0x0C); 241 | } 242 | 243 | 244 | 245 | void display() // Display ON with Cursor OFF 246 | { 247 | command(0x0C); 248 | } 249 | void noDisplay() // Display OFF 250 | { 251 | command(0x08); 252 | } 253 | 254 | 255 | 256 | void scrollDisplayLeft() // Scrolls the contents of the 257 | { // display(text and cursor) one space to the left 258 | command(0x18); 259 | } 260 | void scrollDisplayRight() // Scrolls the contents of the 261 | { // display(text and cursor) one space to the right 262 | command(0x1C); 263 | } 264 | 265 | 266 | 267 | void autoscroll() // This causes each character output to the display to push previous 268 | { // characters over by one space in right to left direction 269 | command(0x07); 270 | } 271 | void noAutoscroll() // Turns off automatic scrolling of the LCD. 272 | { 273 | command(0x06); 274 | } 275 | 276 | 277 | 278 | 279 | void createChar(int num,unsigned int *charArray)// Takes input two arguments 280 | { // 1st is a number between 0-7, 281 | int i=0; // which maps to eight base address 282 | command(base_address[num]); // 2nd is an array of 8 integers, 283 | while(i<8) // each integer is formed by 5 bits 284 | { // which determine the pixels in the 285 | data(charArray[i]); // row same as the index of that integer 286 | i++; // 287 | } // Before printing the character, one must 288 | } // set cursor else cursor won't get printed. 289 | // To print Created Character, one can use data() function. 290 | // Just pass a number between 0-7 as an argument in data() function. 291 | // 292 | // Example: To print value stored at zero 293 | // data(0); CORRECT 294 | // data('0'); INCORRECT 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /AVR(atmega328p) Library for LCD JHD162A/README.md: -------------------------------------------------------------------------------- 1 | #AVR(atmega328p) Library for LCD JHD162A 2 | 3 | ##Requirements: 4 | * Bread Board 5 | * Arduino Uno with Atmega328p 6 | * LCD JHD162A 7 | * Push Button 8 | * 1k Resistor 9 | * Jumper Wires 10 | 11 | 12 | ##Summary: 13 | Liquid Crystal Displays are important in projects where interaction with Human is involved. LCD JHD162A is a small LCD which can be used with atmega328p. It has 16 columns and 2 row, therefore 32 segments. Each segment is composed of 8 rows of 5 dots.
14 | Although this module is very versatile and handy but it’s very tricky to use. Arduino IDE has a library which contain important functions to get this module up and running.
15 | I wanted to build a library for Atmega328p which does almost similar functions as [LiquidCrystal Library] in Arduino IDE. Interfacing with LCD is a task in itself one has to learn and understand the working of LCD in order to use it even for a simple project.
16 | This library don’t require any in depth knowledge of LCD JHD162A and it’s working.
17 | Just include lcd.h in your source code and you are ready to go.
18 | 19 | 20 | 21 | ##Project's Video: 22 | [https://www.youtube.com/watch?v=AQ7CQQZPDSY] 23 | 24 | ##Circuit Diagram: 25 | ![alt text][circuit diagram] 26 | 27 | 28 | ##Project Images 29 | ![alt text][Image_1] 30 | ![alt text][Image_2] 31 | 32 | 33 | 34 | ##Description: 35 | ###How I am uploading code into arduino: 36 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
37 | Then, just type these three commands, in the same order, on your terminal / cmd. 38 | 39 | ```sh 40 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os lcd.c main.c -o main.elf 41 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 42 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 43 | ``` 44 | 45 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 46 | 47 | ###Interfacing LCD JHD162A: 48 | 49 | So, LCD JHD162A can be used in either 8-bit mode or in 4-bit mode. As we are using Atmega328p, I prefer not to waste precious input/output pin on LCD, so I’ll be using 4-bit mode to interface with LCD. Although interfacing in 4-bit mode comes with a cost, cost of time. Same 8-bit data takes twice the time in 4-bit mode than in 8-bit mode but this difference in time is in milliseconds and most of our application require more i/o pins over that millisecond difference.
50 | 51 | Input can be classified into two types:
52 | 1. command: These are instructions given to LCD, to initialize and manipulate data.
53 | 2. data: As the name suggest, this can be any thing which user wants to display.
54 | 55 | Both commands and data are of 8-bits, therefore, to complete a single transmission two 4-bit cycles are required. 56 | To distinguish whether 1 byte of data is transmitted or 1 byte of command is being transmitted, one more input is used, that is Register Select bit. Whenever Register Select bit is set transmitted 8-bits are interpreted as data and whenever Register Select bit is cleared(not set)transmitted 8-bits are interpreted as commands.
57 | Now, LCD is lot slower than our microcontroller, therefore, we need to check whether lcd is free and can take input from our microcontroller, for this Read/Write bit is used. Whenever R/W bit is set we can read LCD busy status on pin D7, if D7 is High then LCD is busy in processing some stuff and if D7 is low then LCD is ready to accept new instructions or data, we can clear R/W bit to initialize writing process.
58 | <--------------------------------------------------OR------------------------------------------>
59 | As can be seen above usage R/W pin is very complex, what we can do is instead of reading LCD’s status we can permanently clear R/W bit (ie, connect R/W pin to ground) and give substantial amount of delay in which any instruction can be processed. In this way we are again compromising in terms of time but complexity of our code decreases with huge factor, with respect to the extra time (generally it's in microseconds).
60 | Again most of our applications don’t even require this amount of precision in terms time.
61 | We need to tell lcd whenever we want to transmit a command or data. This is done using enable bit. Whenever enable bit set, LCD is able to see the data present on data lines in our case data line is 4-bit wide.
62 | 63 | 64 | **So, now sequence of transmitting a 4-bit Data* will be:**
65 | 1. Put the information on the Data* line
66 | 2. Select whether its a command or data
67 | 3. Tell LCD Data* is ready to read(by setting enable bit)
68 | 4. Give sufficient amount of time to read
69 | 5. Clear enable bit
70 | 6. Give sufficient amount of time to process
71 | 72 | \*I have used Data* to represent data+command combined
73 | For more information you can refer the [Datasheet] of JHD162A.
74 | 75 | 76 | 77 | 78 | ##Explanation of Functions in this Library: 79 | I tried to keep library similar to LiquidCrystal library in Arduino IDE. I included some function from my side too.
80 | 81 | 1. command(): Takes in an 8-bit command breaks it in chunks of 4-bit and transmit it to LCD.
82 | 2. data(): Takes in an 8-bit data(generally ASCII characters) breaks it in chunks of 4-bit and transmit it to LCD.
83 | 3. start(): It initializes the LCD with most suitable configuration 84 | * LCD in 5x8 and 4-bit mode 85 | * Display ON cursor OFF 86 | * Increment cursor by one after every byte of data 87 | * Don't shift display after every byte of data 88 | * no auto scrolling 89 | 4. Send_A_String(): Takes a string that is to be displayed as an input, breaks it and then transmit each character using data(). **NOTE:-** maximum character in a string should be less than 16, after 16th character everything will be ignored.
90 | 5. cut(): Works same as Send_A_String(), except maximum number of character is 32. After 16th character, 17th character starts from second row.
91 | 6. Send_An_Integer(): Takes input an integer of long type, converts it into a string and then displays it on LCD. It use Send_A_String() for displaying.
92 | 7. setCursor(): Indexing starts from 0. Therefore, 0<=row<=1 and 0<=column<=15. If arguments are outside the the specified range, then function will not work and ignore the values.
93 | 8. clearScreen(): Clears the screen and returns cursor to (0,0) position.
94 | 9. home(): Returns cursor to (0,0) position.
95 | 10. cursor(): Shows cursor as an underscore.
96 | 11. noCursor(): Hides the cursor.
97 | 12. blink(): Shows cursor as a blinking black spot.
98 | 13. noBlink(): Hides the cursor.
99 | 14. display(): Turns ON the display with cursor OFF.
100 | 15. noDisplay(): Turns display OFF.
101 | 16. scrollDisplayLeft(): Scrolls the contents of the display(text and cursor) one space to the left.
102 | 17. scrollDisplayRight(): Scrolls the contents of the display(text and cursor) one space to the right.
103 | 18. autoscroll(): This causes each character output to the display to push previous characters over by one space in right to left direction.
104 | 19. noAutoscroll(): Turns off automatic scrolling of the LCD.
105 | 20. changeChar(): Takes input two arguments 106 | * 1st is a number between 0-7, which maps to seven base addresses 107 | * 2nd is an array of 8 integers, each integer is formed by 5 bits which determine the pixels in the row same as the index of that integer. 108 | 109 | **NOTE:-** Before printing the character, one must set cursor else cursor won't get printed.
110 | To print Created Character, one can use data() function. Just pass a number between 0-7 as an argument in data() function.
111 | 112 | *Example:* To print value stored at zero
113 | data(0); CORRECT
114 | data('0'); INCORRECT
115 | 116 | 117 | ##Getting started with this Library: 118 | There are three files:
119 | 1. main.c contains the source code of your application(In this case this example).
120 | 2. lcd.c contains definition of all the functions that are included in the library.
121 | 3. lcd.h contains prototype of the functions in lcd.c.
122 | For my source code to work, one need to put all three file in same directory. You can modify it and put these three files anywhere you want.
123 | **Connections:**
124 | In this example i’ve added a push button as can be seen in circuit diagram, you can remove it and add anything depending on your application.
125 | 126 | 127 | 128 | 129 | ##Published on Engineer's Garage 130 | [http://www.engineersgarage.com/contribution/avratmega328p-library-lcd-jhd162a] 131 | 132 | 133 | 134 | [LiquidCrystal Library]: http://www.arduino.cc/en/Reference/LiquidCrystal 135 | [Datasheet]: http://www.itron.com.cn/PDF_file/JHD162A%20SERIES.pdf 136 | [https://www.youtube.com/watch?v=AQ7CQQZPDSY]: https://www.youtube.com/watch?v=AQ7CQQZPDSY 137 | 138 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/AVR%28atmega328p%29%20Library%20for%20LCD%20JHD162A/circuit%20diagram.jpg "circuit diagram" 139 | 140 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/AVR%28atmega328p%29%20Library%20for%20LCD%20JHD162A/Project_image001.jpg "Image_1" 141 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/AVR%28atmega328p%29%20Library%20for%20LCD%20JHD162A/Project_image002.jpg "Image_2" 142 | 143 | [avr­libc]: http://www.nongnu.org/avr-libc/ 144 | [winAVR]: https://sourceforge.net/projects/winavr/ 145 | 146 | [http://www.engineersgarage.com/contribution/avratmega328p-library-lcd-jhd162a]: http://www.engineersgarage.com/contribution/avratmega328p-library-lcd-jhd162a 147 | 148 | 149 | -------------------------------------------------------------------------------- /ADC in Atmega328p/README.md: -------------------------------------------------------------------------------- 1 | #ADC in Atmega328p 2 | 3 | ##Requirements: 4 | * Bread Board 5 | * Arduino Uno with atmega328p 6 | * LDR 7 | * NTC 8 | * Two LEDs 9 | * Jumper Wires 10 | 11 | 12 | ##Summary: 13 | I made this to get power and control of every register using AVR-C and the ease of Arduino’s premade circuit along with FTDI chip. I used few simple commands to compile and upload the AVR-C code on my Arduino. By using Arduino I didn’t had worry about FTDI chip, reference for ADC voltage and other peripheral circuitry and by using AVR-C I had control over each and every register which isn’t possible while working with Arduino IDE. 14 | 15 | This circuit demonstrate the working of ADC in atmega328p using interrupts, using two different kinds of sensors one is LDR it’s resistance decrease with increase in light intensity other is NTC it’s resistance decreases with increase in temperature. 16 | 17 | My arduino is equipped with atmega328p, to get port mapping you can refer to Arduino [Port Manipulation] , this is reference of atmega168, newer chip atmega328p follows the same pin out of atmega168. 18 | 19 | For more detailed information and references you can checkout datasheet of Atmega328p. 20 | [Atmega328p datasheet] 21 | 22 | 23 | ##Project's Video 24 | [https://www.youtube.com/watch?v=a2v7ayJu-cU&feature=youtu.be] 25 | 26 | ##Circuit Diagram: 27 | ![alt text][circuit diagram] 28 | 29 | 30 | ##FLOW CHART FOR THIS PROGRAM: 31 | ![alt text][flow chart] 32 | 33 | 34 | ##Project Image 35 | ![alt text][Image_1] 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ##Description: 44 | 45 | ###How I am uploading code into arduino: 46 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
47 | Then, just type these three commands, in the same order, on your terminal / cmd. 48 | 49 | ```sh 50 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os main.c -o main.elf 51 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 52 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 53 | ``` 54 | 55 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 56 | 57 | 58 | ###Little bit of description of registers being used: 59 | | | | | | ADCSRA | | | | | 60 | |:----------------:|:----:|:----:|:-----:|:----:|:----:|:-----:|:-----:|:-----:| 61 | | Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 62 | | 0x7A | ADEN | ADSC | ADATE | ADIF | ADIE | ADPS2 | ADPS1 | ADPS0 | 63 | | Initial Value | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 64 | 65 | 66 | * Bit 7 – ADEN: ADC Enable 67 | Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off. Turning the ADC off while a conversion is in progress, will terminate this conversion. 68 | * Bit 6 – ADSC: ADC Start Conversion 69 | In Single Conversion mode, write this bit to one to start each conversion. 70 | * Bit 5 – ADATE: ADC Auto Trigger Enable 71 | When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start a conversion on a positive edge of the selected trigger signal. 72 | * Bit 4 – ADIF: ADC Interrupt Flag 73 | This bit is set when an ADC conversion completes and the Data Registers are updated. 74 | * Bit 3 – ADIE: ADC Interrupt Enable 75 | When this bit is written to one and the I-bit in SREG is set, the ADC Conversion Complete Interrupt is activated. 76 | * Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits 77 | These bits determine the division factor between the system clock frequency and the input clock to the ADC. 78 | 79 | 80 | | | | | | ADMUX | | | | | 81 | |:----------------:|:----:|:----:|:-----:|:----:|:----:|:-----:|:-----:|:-----:| 82 | | Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 83 | | 0x7A |REFS1 |REFS0 | ADLAR | - | MUX3 | MUX2 | MUX1 | MUX0 | 84 | | Initial Value | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 85 | 86 | 87 | * Bit 7 – ADEN: ADC Enable 88 | Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off. Turning the ADC off while a conversion is in progress, will terminate this conversion. 89 | * Bit 6 – ADSC: ADC Start Conversion 90 | In Single Conversion mode, write this bit to one to start each conversion. 91 | * Bit 5 – ADATE: ADC Auto Trigger Enable 92 | When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start a conversion on a positive edge of the selected trigger signal. 93 | * Bit 4 – ADIF: ADC Interrupt Flag 94 | This bit is set when an ADC conversion completes and the Data Registers are updated. 95 | * Bit 3 – ADIE: ADC Interrupt Enable 96 | When this bit is written to one and the I-bit in SREG is set, the ADC Conversion Complete Interrupt is activated. 97 | * Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits 98 | These bits determine the division factor between the system clock frequency and the input clock to the ADC. 99 | 100 | 101 | 102 | ###Explanation of code: 103 | 104 | After defining appropriate clock frequency (F_CPU=16,000,000)and including essential libraries <avr/io.h>,<util/delay.h>,<avr/interrupt.h>.
105 | I made a function setup_adc() which setup configuration of ADC.This function writes 11001111 in register ADCSRA and 0110000 in register ADMUX.
106 | 107 | | | | | | ADCSRA | | | | | 108 | |:-----------------------:|:----:|:----:|:-----:|:----:|:----:|:-----:|:-----:|:-----:| 109 | | 0x7A | ADEN | ADSC | ADATE | ADIF | ADIE | ADPS2 | ADPS1 | ADPS0 | 110 | | Value after Setup_adc() | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 111 | 112 | 113 | According to data sheet in order to use 10bit ADC, I should set ADC frequency 114 | between 50KHz-200KHz, according to this data my pre-scalar value must be in the range of 115 | 80-320 and the only available value in this range is 128. 116 | * ADEN bit enables ADC 117 | * ADPS2 , ADPS1 , ADPS0 sets a prescaler of 128 ,ie, now ADC works at a frequency of 125KHz 118 | *frequency of ADC= 1,60,00,000/128 = 125KHz* 119 | * ADIE enables ADC interrupt 120 | * ADSC it starts the conversion 121 | 122 | 123 | | | | | | ADMUX | | | | | 124 | |:-----------------------:|:----:|:----:|:-----:|:----:|:----:|:-----:|:-----:|:-----:| 125 | | 0x7A |REFS1 |REFS0 | ADLAR | - | MUX3 | MUX2 | MUX1 | MUX0 | 126 | | Value after Setup_adc() | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 127 | 128 | * ADLAR for left adjusted result 129 | * REFS0=1 and REFS1=0 to use Vcc as reference voltage 130 | 131 | In main() function I set the value 00110000 in DDRD(Direction Register for Port D), ie, defining Pin 5 and 7 as output. Then iI called sei() which enabled global interrupt by setting the I bit in status register (SREG), its a build in function in <avr/interrupt.h> library.
132 | Then setup_adc() function is called after which an infinite while loop is started. 133 | 134 | Last part include the code which has to be executed after every ADC conversion,ie whenever an interrupt is generated. This code goes into ISR() block and respective interrupt vector is passed an argument(in this case ADC_vect).
135 | In ISR(), I store the 10-bit result in variable adc_ten_bit_value by simple manipulation as the result is left adjusted.
136 | I check values of LDR and NTC alternatively after every conversion ,ie, value of mux3, mux2, mux1, mux0 in ADMUX must be changed after every conversion, in case of my source code toggling of value present in mux0 after every conversion will do the work, its record is kept in variable value_of_mux0.
137 | Then simple conditional statements are placed for manipulation of output ports.
138 | 139 | 140 | 141 | ###Explanation of circuit and hardware components: 142 | 143 | As can be seen in circuit diagram two potential dividers are made one with LDR and 1kohm resistor and other with NTC and 1kohm resistor. Wires from the junction of LDR and register is feed to Arduino PC1(pinA1) and wires from the junction of NTC and register is feed to Arduino PC0(pinA0), ie, both pins will measure potential drop across the sensors. 144 | Now, I took two LEDs and connected their cathode to GND and anode of one LED to PD5(pin5) and anode of other to PD7(pin7).
145 | LED connected to PD5(pin5) will glow when value of LDR is less than 10(critical value), similarly LED connected to PD7(pin7) will glow when the value of NTC is greater than 133(critical value).
146 | 147 | 148 | 149 | 150 | ##Published on Engineer's Garage 151 | [http://www.engineersgarage.com/contribution/programing-arduino-using-avr-c] 152 | 153 | 154 | [Port Manipulation]: http://www.arduino.cc/en/Reference/PortManipulation 155 | [Atmega328p datasheet]: http://www.atmel.com/Images/doc8161.pdf 156 | [https://www.youtube.com/watch?v=a2v7ayJu-cU&feature=youtu.be]: https://www.youtube.com/watch?v=a2v7ayJu-cU&feature=youtu.be 157 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/ADC%20in%20Atmega328p/circuit%20diagram.jpg "circuit diagram" 158 | [flow chart]: https://github.com/varun13169/Engineers_Garage/blob/master/ADC%20in%20Atmega328p/flow%20chart.jpg "flow chart" 159 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/ADC%20in%20Atmega328p/Project_image001.jpg "Image_1" 160 | 161 | [avr­libc]: http://www.nongnu.org/avr-libc/ 162 | [winAVR]: https://sourceforge.net/projects/winavr/ 163 | 164 | [http://www.engineersgarage.com/contribution/programing-arduino-using-avr-c]: http://www.engineersgarage.com/contribution/programing-arduino-using-avr-c 165 | 166 | -------------------------------------------------------------------------------- /Reaction Time Game using External and Pin Change Interrupts in Atmega328p /main.c: -------------------------------------------------------------------------------- 1 | #define F_CPU 16000000UL 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include"lcd.h" 8 | 9 | /**************** Variables *******************/ 10 | int player_flag=1; 11 | int flag=1; 12 | int led_number; 13 | int player1_count; 14 | int player2_count; 15 | int count=0; 16 | int start_flag=0; 17 | int i; 18 | volatile uint8_t portbhistory = 0x00; 19 | /**********************************************/ 20 | 21 | 22 | /************ Functions Prototype *************/ 23 | int random_number(); 24 | void player1(); 25 | void player2(); 26 | /**********************************************/ 27 | 28 | /**** Decimal Values to Display Special Characters ****/ 29 | unsigned int s1[]={31,17,17,17,17,17,17,17}; 30 | unsigned int s2[]={31,8,4,2,1,0,0,0}; 31 | unsigned int s3[]={0,0,0,0,0,17,10,4}; 32 | unsigned int s4[]={31,2,4,8,16,0,0,0}; 33 | /******************************************************/ 34 | 35 | 36 | int main(void) 37 | { 38 | DDRB |= 0xFF; // Declaring pins 8,9,10,11,12,13 as output 39 | DDRD |= 0xF0; // Declaring pins 4,5,6,7 as output 40 | DDRC |= 0x00; // Declaring all pins of PortC as input 41 | PORTC |= ((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3)); // Enables the pull-up 42 | 43 | _delay_ms(500); 44 | start(); // Initialises LCD display 45 | _delay_ms(100); 46 | clearScreen(); 47 | 48 | 49 | EICRA = 1<0;i--) 94 | { // 95 | display(); // 96 | setCursor(1,11); // 97 | PORTB |= 0B00111100; // Indicates player 1 98 | Send_An_Integer(i); // to get reddy, 99 | _delay_ms(500); // before the start of Game 100 | noDisplay(); // 101 | PORTB &= 0B11000011; // 102 | _delay_ms(500); // 103 | } 104 | setCursor(1,11); 105 | Send_A_String("Go !!"); 106 | display(); 107 | _delay_ms(500); 108 | sei(); // Enables interrupt 109 | /***************************************/ 110 | 111 | 112 | 113 | /************** Player 1 ***************/ 114 | count=0; // Initializes the score 115 | clearScreen(); 116 | Send_A_String("Player 1 score:"); 117 | setCursor(1,0); 118 | Send_An_Integer(count); 119 | for(i=0;i<4;i++) 120 | { 121 | setCursor(1,0); // This loop gives player 1 122 | player1(); // four chances and 123 | Send_An_Integer(count); // displays score after every chance 124 | } 125 | player1_count=count; 126 | _delay_ms(500); 127 | /***************************************/ 128 | 129 | 130 | 131 | 132 | /*********** Player 2 Readdy************/ 133 | cli(); // Disables interrupt 134 | clearScreen(); 135 | Send_A_String("Player 2"); 136 | setCursor(1,0); 137 | Send_A_String("Get Reddy "); 138 | for(i=3;i>0;i--) 139 | { 140 | display(); // 141 | setCursor(1,11); // 142 | PORTB |= 0B00111100; // Indicates player 2 143 | Send_An_Integer(i); // to get reddy, 144 | _delay_ms(500); // before the start of Game 145 | noDisplay(); // 146 | PORTB &= 0B11000011; // 147 | _delay_ms(500); // 148 | } 149 | setCursor(1,11); 150 | Send_A_String("Go !!"); 151 | display(); 152 | _delay_ms(500); 153 | sei(); // Enables interrupt 154 | /***************************************/ 155 | 156 | 157 | 158 | 159 | /************** Player 2 ***************/ 160 | count=0; // Initializes the score 161 | clearScreen(); 162 | Send_A_String("Player 2 score:"); 163 | setCursor(1,0); 164 | Send_An_Integer(count); 165 | for(i=0;i<4;i++) 166 | { 167 | setCursor(1,0); // This loop gives player 2 168 | player2(); // four chances and 169 | Send_An_Integer(count); // displays score after every chance 170 | } 171 | player2_count=count; 172 | _delay_ms(500); 173 | /***************************************/ 174 | 175 | 176 | 177 | /*********************** Decide Winner ********************/ 178 | cli(); // Disables interrupt 179 | PORTB &= 0B11000011; // Turn off all the LEDs 180 | _delay_ms(1000); 181 | 182 | if(player1_count > player2_count) // 183 | { // 184 | clearScreen(); // 185 | Send_A_String("Player 1 is"); // 186 | setCursor(1,0); // 187 | Send_A_String("faster"); // 188 | } // Checks which player got 189 | else // the lowest time and 190 | { // accordingly declares the winner 191 | clearScreen(); // 192 | Send_A_String("Player 2 is"); // 193 | setCursor(1,0); // 194 | Send_A_String("faster"); // 195 | } // 196 | _delay_ms(2000); // 197 | /************************************************************/ 198 | 199 | 200 | 201 | /************** Restart ***************/ 202 | start_flag=0; 203 | clearScreen(); 204 | Send_A_String(" Push Button"); 205 | setCursor(1,0); 206 | Send_A_String(" To Play Again"); 207 | 208 | setCursor(0,1); 209 | data(0); 210 | setCursor(1,0); 211 | data(1); 212 | setCursor(1,1); 213 | data(2); 214 | setCursor(1,2); 215 | data(3); 216 | /**************************************/ 217 | sei(); 218 | } 219 | return 0; 220 | } 221 | 222 | 223 | 224 | void player1() 225 | { 226 | 227 | player_flag=1; 228 | led_number = random_number(); // get a random number between 0-3 229 | while(player_flag==1) 230 | { 231 | _delay_ms(1); // This loop counts the time 232 | count++; // in milli-seconds 233 | } 234 | player_flag = 1; // Just to re-initiallise 235 | 236 | } 237 | 238 | 239 | void player2() 240 | { 241 | player_flag=1; 242 | led_number = random_number(); // get a pseudo random number between 0-3 243 | while(player_flag==1) 244 | { 245 | _delay_ms(1); // This loop counts the time 246 | count++; // in milli-seconds 247 | } 248 | player_flag = 1; // Just to re-initiallise 249 | 250 | } 251 | 252 | int random_number() 253 | { 254 | int rand_value = rand()%4; // Genrates a pseudo random number between 0-3 255 | // I'm using pseudo random number because it's 256 | switch(rand_value) // easy to debug and show the concept of intrrupts. 257 | { // 258 | case 0: // Used to genrate a pseudo random number 259 | PORTB = 1< 12 | Delay pauses the whole program, so if one is using delay for 10 seconds everything will pause for those 10 seconds, therefore nothing can be done in those 10 seconds.
13 | Although if we use interrupt, there is a separate hardware known as timer which counts the clock ticks and generate interrupt, after specified number of clock ticks have been counted. 14 | 15 | In this project I’m using LCD JHD162A. It has 2 rows and 16 columns. 16 | 17 | In this project I build a task scheduler which switches between two threads in an interval of 5.5 seconds.
18 | First task(thread 1) is to increment an integer value displayed on first row of LCD every second.
19 | Second task(thread 2) is decrement an integer value displayed on second row every two seconds.
20 | Both integers start from Zero. 21 | 22 | **Example:**
23 | 1. t1 is running and increments the integer in the first row every second
24 | 2. After 5.5 seconds, t1 stops and t2 starts decrementing the integer in the second row every 2 seconds
25 | 3. After 5.5 seconds, stop t2, start t1, go back to 1
26 | 27 | ![alt text][timming diagram] 28 | 29 | A thread is a lightweight process that is executed independently. But due to hardware limitation let's assume that a thread is simply a function manipulating one of the integers mentioned above. Since Atmega328P is equipped with only one ALU, either thread1 or thread2 is able to run. They can never run at the same time.
30 | I’m using arduino equipped with atmega328p for this project, to get port mapping you can refer to [Arduino Port Manipulation] , this is reference for atmega168, newer chip atmega328p follows the same pin out of atmega168.
31 | For more detailed information and references you can checkout datasheet of Atmega328p. 32 | [Atmega328p datasheet] 33 | 34 | 35 | 36 | ##Project's Video: 37 | [https://www.youtube.com/watch?v=9XtL2W2DUp8&feature=youtu.be] 38 | 39 | ##Circuit Diagram: 40 | ![alt text][circuit diagram] 41 | 42 | 43 | ##Project Images 44 | ![alt text][Image_1] 45 | ![alt text][Image_2] 46 | 47 | 48 | 49 | ##Description: 50 | ###How I am uploading code into arduino: 51 | Download and install AVR toolchain, for Linux [avr­libc] and for windows [winAVR].
52 | Then, just type these three commands, in the same order, on your terminal / cmd. 53 | 54 | ```sh 55 | $ avr-gcc -g -mmcu=atmega328p -Wall -Os lcd.c main.c -o main.elf 56 | $ avr-objcopy -j .text -j .data -O ihex main.elf main.hex 57 | $ sudo avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB* -b 57600 -e -U flash:w:main.hex 58 | ``` 59 | 60 | First command is used to convert source code to .elf file, second command is used to convert that .elf file to .hex file which can be uploaded on atmega328p, third command is used to upload that .hex file. 61 | 62 | ###Intro to Atmega328p and it’s timers: 63 | 64 | Atmega328p is equipped ,viz. timer0, timer1, timer2; two are 8-bits and one is 16-bit. Maximum number of clock ticks that a timer can count depends on the size of the register.
65 | Timer 0 and timer 2 use two different 8-bit register, whereas, timer 1 is use a 16-bit register. 66 | 67 | An 8-bit register can count upto 2^8 = 256(0 to 255) similarly 16-bit register can count up 2^16 = 65536(0 to 65535). With the available resources I can generate an interrupt at every (65536/clock freq) 65536/1,60,00,000 = 4.0959375ms.
68 | To increase this maximum time, every timer is given a set of pre-scalars, which are in power of 2’s. A prescaler divides the clock freq by that number. In 16-bit timer maximum pre-scalar available is 1024, therefore now I can generate an interrupt (65536/(clk freq/1024)) 65536*1024/1,60,00,000 = 4.19424 sec.
69 | Same goes for 8-bit timer. 70 | 71 | A simple formula
72 | *Count = (Required Delay * Clock Frequency)/Prescaler - 1* 73 | 74 | 75 | ###Little bit of description about timer being used: 76 | 77 | | | | | | TCCR1B | | | | | 78 | |:----------------:|:----:|:----:|:-----:|:----:|:----:|:-----:|:-----:|:-----:| 79 | | Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 80 | | 0x7A |ICNC1 |ICES1 | - |WGM13 |WGM12 | CS12 | CS11 | CS10 | 81 | | Initial Value | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 82 | 83 | * Bit 7 – ICNC1: Input Capture Noise Canceler
84 | Setting this bit (to one) activates the Input Capture Noise Canceler. When the noise canceler is activated, the input from the Input Capture pin (ICP1) is filtered.
85 | * Bit 6 – ICES1: Input Capture Edge Select
86 | This bit selects which edge on the Input Capture pin (ICP1) that is used to trigger a capture event.
87 | * Bit 5 – Reserved Bit
88 | This bit is reserved for future use. For ensuring compatibility with future devices, this bit must be written to zero when TCCR1B is written.
89 | * Bit 4:3 – WGM13:2: Waveform Generation Mode
90 | See TCCR1A Register description.
91 | * Bit 2:0 – CS12:0: Clock Select
92 | The three Clock Select bits select the clock source to be used by the Timer/Counter
93 | 94 | 95 | 96 | 97 | | | | | | TCCR1B | | | | | 98 | |:----------------:|:----:|:----:|:-----:|:----:|:----:|:-----:|:-----:|:-----:| 99 | | Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 100 | | 0x7A | - | - | ICIE1 | - | - |OCIE1B |OCIE1B | TOIE1 | 101 | | Initial Value | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 102 | 103 | * Bit 7, 6 – Res: Reserved Bits
104 | These bits are unused bits in the ATmega48PA/88PA/168PA/328P, and will always read as zero.
105 | * Bit 5 – ICIE1: Timer/Counter1, Input Capture Interrupt Enable
106 | When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Counter1 Input Capture interrupt is enabled.
107 | * Bit 4, 3 – Res: Reserved Bits
108 | These bits are unused bits in the ATmega48PA/88PA/168PA/328P, and will always read as zero.
109 | * Bit 2 – OCIE1B: Timer/Counter1, Output Compare B Match Interrupt Enable
110 | When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Counter1 Output Compare B Match interrupt is enabled. The corresponding Interrupt Vector is executed when the OCF1B Flag, located in TIFR1, is set.
111 | * Bit 1 – OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable
112 | When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Counter1 Output Compare A Match interrupt is enabled. The corresponding Interrupt Vector is executed when the OCF1A Flag, located in TIFR1, is set.
113 | * Bit 0 – TOIE1: Timer/Counter1, Overflow Interrupt Enable
114 | When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Counter1 Overflow interrupt is enabled.
115 | 116 | 117 | 118 | 119 | ###Description about the task: 120 | * Whats my task 121 | My task is to simulate threading. I designed two task one in which a counter increments after every second and another in which counter decrements after every two seconds.
122 | Both the tasks are switched every 5.5 seconds and previous state of the task is preserved. 123 | 124 | * timers relation 125 | In this project I’m using timer1, which is a 16 bit timer therefore maximum count it can go for is 2^16 = 65536. 126 | Minimum value of time that I want is 0.5 seconds.
127 | My Arduino is equipped with a frequency oscillator, having freq. 1,60,00,000Hz. 128 | 129 | Therefore to generate an interrupt at every 0.5 seconds
130 | *Count = (0.5 * 1,60,00,000)/1 - 1 = 79,99,999*
131 | I need a register capable of counting 79,99,999(which is not available). 132 | 133 | So I decided to use a pre-scalar with a value of 256. Now for every to generate an interrupt at every 0.5 seconds.
134 | *Count = (0.5 * 1,60,00,000)/256 - 1 = 31249*
135 | I need a register capable of counting 31249(16 bit timer with a prescaler of 256 can easily do that). 136 | Therefore, after every 0.5 seconds an interrupt is generated. 137 | 138 | * logic 139 | Both thread follows a pattern which can be simulated by generating an interrupt of 0.5 seconds. Thread 1 repeats itself after every 22 seconds(includes the time of other thread which will be executed in between) and thread 2 repeats itself after every 77 seconds(includes the time of other thread which will be executed in between).
140 | Therefore if a variable is initialised to keep track on the pattern for a specific thread, it can be reseted to zero after every complete cycle of that specific thread. 141 | 142 | 143 | 144 | As can be seen below, thread 1 repeats its pattern after two iterations. 145 | ![alt text][pattern for thread1] 146 | 147 | 148 | And thread 2 repeats its pattern after four iterations. 149 | ![alt text][pattern for thread2] 150 | 151 | 152 | 153 | 154 | ###Description of Source Code: 155 | I used my own library lcd.h to display integer value of thread 1 and thread 2 on 16x2 LCD.
156 | First I initialised timer() function and defined relevant variables globally, then in main() function I declared pin 4,5,6,7,8,9 as output and I initialized lcd via start() allowed global interrupt via sei() and initialised timer via timer().
157 | After initializing and defining necessary things I displayed 0 on both rows of lcd, and started an infinite loop.
158 | Algorithm that I’m using is in ISR() block, which is executed on every 0.5 second interrupt.
159 | For more details please refer source code, it has been explained with comments in it.
160 | 161 | 162 | 163 | 164 | ##Published on Engineer's Garage 165 | [http://www.engineersgarage.com/contributions/threading-and-timers-atmega328p] 166 | 167 | 168 | [timming diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/Timers%20in%20Atmega328p/timming%20diagram.jpg "timming diagram" 169 | 170 | [Arduino Port Manipulation]: http://www.arduino.cc/en/Reference/PortManipulation 171 | [Atmega328p datasheet]: http://www.atmel.com/Images/doc8161.pdf 172 | [https://www.youtube.com/watch?v=9XtL2W2DUp8&feature=youtu.be]: https://www.youtube.com/watch?v=9XtL2W2DUp8&feature=youtu.be 173 | [circuit diagram]: https://github.com/varun13169/Engineers_Garage/blob/master/Timers%20in%20Atmega328p/circuit%20diagram.jpg "circuit diagram" 174 | 175 | [Image_1]: https://github.com/varun13169/Engineers_Garage/blob/master/Timers%20in%20Atmega328p/Project_image001.jpg "Image_1" 176 | [Image_2]: https://github.com/varun13169/Engineers_Garage/blob/master/Timers%20in%20Atmega328p/Project_image002.jpg "Image_2" 177 | 178 | [avr­libc]: http://www.nongnu.org/avr-libc/ 179 | [winAVR]: https://sourceforge.net/projects/winavr/ 180 | 181 | [pattern for thread1]: https://github.com/varun13169/Engineers_Garage/blob/master/Timers%20in%20Atmega328p/pattern%20for%20thread1.jpg "pattern for thread1" 182 | 183 | [pattern for thread2]: https://github.com/varun13169/Engineers_Garage/blob/master/Timers%20in%20Atmega328p/pattern%20for%20thread2.jpg "pattern for thread2" 184 | 185 | [http://www.engineersgarage.com/contributions/threading-and-timers-atmega328p]: http://www.engineersgarage.com/contributions/threading-and-timers-atmega328p 186 | 187 | 188 | 189 | --------------------------------------------------------------------------------