📜 ⬆️ ⬇️

Homemade IR Remote for iRobot Roomba

A survey in my previous post “Controlling the iRobot Roomba using a vacuum cleaner via IR” showed that the community is interested in finding out how to make the IR remote itself for Roomb's. So, welcome! =)



Remote control scheme:


')
I used:


Initially, I planned to make a “Spartan” option - a board with buttons in heat shrinkage, but then I decided to put everything in the case. The case chose from what is on sale, I liked the GAINTA G401 . Under it and made a fee:



Button functions:
SW1 - Dock
SW2 - Pause / Power
SW3 - Forward Left
SW4 - Clean
SW5 - Left
SW6 - Forward
SW7 - Spot
SW8 - Right
SW9 - Forward Right

As it turned out later, the SW2 button, which, by design, sends the “Pause” command when pressed, but with a long press of the “Power” button, is not needed, because these functions are performed by the “Clean” button. It works the same way as the button on the robot vacuum cleaner itself: short press to clean, to stop during operation, and long press to turn off. T.ch. if anyone repeats the console - just do not install SW2.

Program listing
/*   - Irobot Roomba.    Atmel ATTINY2313A. FUSE-: Fuse Low Byte: CKDIV|CKOUT|SUT|SKSEL| 0 | 1 |10 |0100 | 0x64 Default 1 | 1 |10 |1100 | 0b11101100=0xEC   3-8  */ //#define F_CPU 7.3728E6 //#define __AVR_ATtiny2313A__ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> /*------<>-----*/ // 39477  // 25,3 : #define P_GEN {TCNT0=0; PORTB |= 0x8; while (TCNT0 < 93); PORTB &= ~0x8; while (TCNT0 < 186);} //Roomba : #define LEFT 129 #define FORWARD 130 #define RIGHT 131 #define SPOT 132 #define DOCK 133 #define CLEAN 136 #define PAUSE 137 #define POWER 138 #define FORWARD_LEFT 139 #define FORWARD_RIGHT 140 #define TEST 170 /*----------------<:>----------------*/ void init(void) { //    /1: CLKPR = (1<<CLKPCE); CLKPR = (0<<CLKPS0)|(0<<CLKPS1)|(0<<CLKPS2)|(0<<CLKPS3); // : PORTD = 0xFF; DDRD = 0x0; PORTB = (1<<PORTB0)|(1<<PORTB1)|(1<<PORTB2); DDRB = (1<<DDB3)|(1<<DDB4); // : GIMSK = 0x30; //(1<<PCIE)|(1<<4); PCMSK = 0x3; //(1<<PCINT0)|(1<<PCINT1); PCMSK2 = 0x7F; } void ir_tx(unsigned char data_ir) { PORTB |= (1<<PB4); //  /*  : 1: __________ 2862uS |988uS |_____ 0: _____ 887uS| 2862uS |__________    ~16870 uS */ unsigned char cnt; // : TCCR0B = (0<<CS12)|(0<<CS11)|(1<<CS10); //   f/1 TCCR1B = (0<<CS12)|(1<<CS11)|(1<<CS10); //   f/64 for (cnt=0; cnt<8; cnt++) { TCNT1=0; if (data_ir & (0x80 >> cnt)) { // 1 while (TCNT1 < 330) P_GEN; while (TCNT1 < (330+114)) ; } else { // 0 while (TCNT1 < 113) P_GEN; while (TCNT1 < (330+114)) ; } } TCNT1=0; while (TCNT1 < 1950) ; PORTB &= ~(1<<PB4); //  } void send_command(void) { volatile unsigned char button_b; volatile unsigned char button_d; volatile unsigned char button_b_new; volatile unsigned char button_d_new; unsigned char pause_cnt = 0; TCCR1B = (0<<CS12)|(1<<CS11)|(1<<CS10); // f/64 TCNT1=0; while (TCNT1 < 346); //346 -  3 ms button_b = ~PINB & ((1<<PINB0)|(1<<PINB1)); button_d = ~PIND & 0x7F; button_b_new = button_b; button_d_new = button_d; while ((button_b == button_b_new)&&(button_d == button_d_new)) { if ((button_b_new == 0) && (button_d_new == 0)) break; if (button_b == (1<<PINB0)) {ir_tx(DOCK);} if ((pause_cnt < 20) && (button_b == (1<<PINB1))) {ir_tx(PAUSE); pause_cnt++;} if (pause_cnt >= 20) {ir_tx(POWER);} if (button_d == (1<<PIND0)) {ir_tx(FORWARD_LEFT);} if (button_d == (1<<PIND1)) {ir_tx(CLEAN);} if (button_d == (1<<PIND2)) {ir_tx(LEFT);} if (button_d == (1<<PIND3)) {ir_tx(FORWARD);} if (button_d == (1<<PIND4)) {ir_tx(SPOT);} if (button_d == (1<<PIND5)) {ir_tx(RIGHT);} if (button_d == (1<<PIND6)) {ir_tx(FORWARD_RIGHT);} button_b_new = ~PINB & ((1<<PINB0)|(1<<PINB1)); button_d_new = ~PIND & 0x7F; } } /*----------------------< :>------------------------*/ ISR(PCINT_B_vect) { cli(); send_command(); sei(); } ISR(PCINT_D_vect) { cli(); send_command(); sei(); } /*-----------------<  >-----------------------*/ int main(void) { init(); sei(); for(;;) { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode(); } } 



Photo assembly:



Signatures of the buttons, of course, look clumsy - now I understand that engraving is not an easy task! :)

The board itself:





The conductors that were supposed to perform on the reverse side made wires.

Video demonstrating the work:




KiCAD project files: RemoteControlPCB.zip .
Firmware: RoombaRemoteControl.elf.hex .

For firmware via USBasp programmer, avrdude program:
 avrdude -p t2313 -c usbasp -U flash:w:./RoombaRemoteControl.elf.hex 

Firmware fuse-bits for working with quartz:
 avrdude -p t2313 -c usbasp -U lfuse:w:0xEC:m 

Source: https://habr.com/ru/post/169967/


All Articles