/* This function is the 'workhorse' of transmitting IR codes. Given the on and off times, it turns on the PWM output on and off to generate one 'pair' from a long code. Each code has ~50 pairs! */ void xmitCodeElement(uint16_t ontime, uint16_t offtime, uint8_t PWM_code ) { TCNT2 = 0; if(PWM_code) { pinMode(IRLED, OUTPUT); // Fast PWM, setting top limit, divide by 8 // Output to pin 3 TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); TCCR2B = _BV(WGM22) | _BV(CS21); } else { // However some codes dont use PWM in which case we just turn the IR // LED on for the period of time. digitalWrite(IRLED, HIGH); } // Now we wait, allowing the PWM hardware to pulse out the carrier // frequency for the specified 'on' time delay_ten_us(ontime); // Now we have to turn it off so disable the PWM output TCCR2A = 0; TCCR2B = 0; // And make sure that the IR LED is off too (since the PWM may have // been stopped while the LED is on!) digitalWrite(IRLED, LOW); // Now we wait for the specified 'off' time delay_ten_us(offtime); }
/* This function is the 'workhorse' of transmitting IR codes. Given the on and off times, it turns on the PWM output on and off to generate one 'pair' from a long code. Each code has ~50 pairs! */ void xmitCodeElement(uint16_t ontime, uint16_t offtime, uint8_t PWM_code ) { // start Timer0 outputting the carrier frequency to IR emitters on and OC0A // (PB0, pin 5) TCNT0 = 0; // reset the timers so they are aligned TIFR = 0; // clean out the timer flags if(PWM_code) { // 99% of codes are PWM codes, they are pulses of a carrier frequecy // Usually the carrier is around 38KHz, and we generate that with PWM // timer 0 TCCR0A =_BV(COM0A0) | _BV(WGM01); // set up timer 0 TCCR0B = _BV(CS00); } else { // However some codes dont use PWM in which case we just turn the IR // LED on for the period of time. PORTB &= ~_BV(IRLED); } // Now we wait, allowing the PWM hardware to pulse out the carrier // frequency for the specified 'on' time delay_ten_us(ontime); // Now we have to turn it off so disable the PWM output TCCR0A = 0; TCCR0B = 0; // And make sure that the IR LED is off too (since the PWM may have // been stopped while the LED is on!) PORTB |= _BV(IRLED); // turn off IR LED // Now we wait for the specified 'off' time delay_ten_us(offtime); }
// This function quickly pulses the visible LED (connected to PB0, pin 5) 4 times void quickflashLED4x( void ) { quickflashLED(); delay_ten_us(15000); // 150 millisec delay quickflashLED(); delay_ten_us(15000); // 150 millisec delay quickflashLED(); delay_ten_us(15000); // 150 millisec delay quickflashLED(); }
void blinkLED(uint8_t count) { while(count--) { delay_ten_us(15000); PORTB |= _BV(LED); delay_ten_us(1000); PORTB &=~ _BV(LED); wdt_reset(); } }
int main(void) { uint8_t i; TCCR1 = 0; // Turn off PWM/freq gen, should be off already TCCR0A = 0; TCCR0B = 0; i = MCUSR; // Save reset reason MCUSR = 0; // clear watchdog flag WDTCR = _BV(WDCE) | _BV(WDE); // enable WDT disable WDTCR = 0; // disable WDT while we setup DDRB = _BV(LED) | _BV(IRLED); // set the visible and IR LED pins to outputs PORTB = _BV(LED) | // visible LED is off when pin is high _BV(IRLED) | // IR LED is off when pin is high _BV(REGIONSWITCH); // Turn on pullup on region switch pin // check the reset flags if (i & _BV(BORF)) { // Brownout // Flash out an error and go to sleep flashslowLEDx(2); tvbgone_sleep(); } delay_ten_us(5000); // Let everything settle for a bit // Starting execution loop delay_ten_us(25000); // turn on watchdog timer immediately, this protects against // a 'stuck' system by resetting it wdt_enable(WDTO_8S); // 1 second long timeout wdt_reset(); // set OCR for Timer1 to output this POWER code's carrier frequency // XXX we need to set the carrier frequency to 32700 Hz, I think OCR0A = freq_to_timerval(32700); // XXX change 733 to 536 to change mode? // XXX emit burst... xmitCodeElement(45, 733, 1); // XXX emit second burst xmitCodeElement(45, 733, 1); // We are done, no need for a watchdog timer anymore wdt_disable(); // flash the visible LED on PB0 4 times to indicate that we're done delay_ten_us(65500); // wait maxtime delay_ten_us(65500); // wait maxtime quickflashLEDx(4); tvbgone_sleep(); }
// This is like the above but way slower, used for when the tvbgone // crashes and wants to warn the user void flashslowLEDx( uint8_t num_blinks ) { uint8_t i; for(i=0;i<num_blinks;i++) { // turn on visible LED at PB0 by pulling pin to ground PORTB &= ~_BV(LED); delay_ten_us(50000); // 500 millisec delay wdt_reset(); // kick the dog // turn off visible LED at PB0 by pulling pin to +3V PORTB |= _BV(LED); delay_ten_us(50000); // 500 millisec delay wdt_reset(); // kick the dog } }
void setup() { Serial.begin(9600); TCCR2A = 0; TCCR2B = 0; digitalWrite(LED, LOW); digitalWrite(IRLED, LOW); pinMode(LED, OUTPUT); pinMode(IRLED, OUTPUT); pinMode(REGIONSWITCH, INPUT); pinMode(TRIGGER, INPUT); digitalWrite(REGIONSWITCH, HIGH); //Pull-up digitalWrite(TRIGGER, HIGH); delay_ten_us(5000); // Let everything settle for a bit // determine region if (digitalRead(REGIONSWITCH)) { region = US; // US DEBUGP(putstring_nl("US")); } else { region = EU; DEBUGP(putstring_nl("EU")); } // Tell the user what region we're in - 3 is US 4 is EU quickflashLEDx(3+region); // Indicate how big our database is DEBUGP(putstring("\n\rNA Codesize: "); putnum_ud(num_NAcodes); );
int main(void) { pre_loop_setup(); while (1) { if ( loop_counter > 1000 ) { second_counter++; loop_counter = 0; } if ( second_counter % 6 == 0 ) { JUST_RED_ON; } else if ( second_counter % 6 == 2 ) { JUST_GREEN_ON; } else if ( second_counter % 6 == 4 ) { JUST_BLUE_ON; } else { ALL_RGB_OFF; } delay_ten_us(100); loop_counter++; } return 0; }
// This function just flashes the visible LED a couple times, used to // tell the user what region is selected void quickflashLEDx( uint8_t x ) { quickflashLED(); while(--x) { wdt_reset(); delay_ten_us(15000); // 150 millisec delay between flahes quickflashLED(); } wdt_reset(); // kick the dog }
void mark(int time) { // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. #ifdef TRIPPY_RGB_WAVE GTCCR |= _BV(COM0A0); // turn on OC0A PWM output #else GTCCR |= _BV(COM1B0); // turn on OC1B PWM output #endif delay_ten_us(time / 10); }
/* Leave pin off for time (given in microseconds) */ void space(int time) { // Sends an IR space for the specified number of microseconds. // A space is no output, so the PWM output is disabled. #ifdef TRIPPY_RGB_WAVE GTCCR &= ~(_BV(COM0A0)); // turn off OC0A PWM output #else GTCCR &= ~(_BV(COM1B0)); // turn off OC1B PWM output #endif delay_ten_us(time / 10); }
void flash_byte(uint8_t data) { #ifdef ENABLE_FLASH_BYTE_CODE for (uint8_t i=0; i<8; i++) { if ( data & 1 ) { PORTB |= rgbMask; // turns off RGB PORTB ^= redMask; // turns on red delay_ten_us(20000); PORTB |= rgbMask; // turns off RGB delay_ten_us(IR_DATA_PRINT_DELAY); } else { PORTB |= rgbMask; // turns off RGB PORTB ^= bluMask; // turns on red delay_ten_us(20000); PORTB |= bluMask; // turns off RGB delay_ten_us(IR_DATA_PRINT_DELAY); } data >>= 1; } #endif }
void tvbgone_sleep( void ) { // Shut down everything and put the CPU to sleep TCCR0A = 0; // turn off frequency generator (should be off already) TCCR0B = 0; // turn off frequency generator (should be off already) PORTB |= _BV(LED) | // turn off visible LED _BV(IRLED); // turn off IR LED wdt_disable(); // turn off the watchdog (since we want to sleep delay_ten_us(1000); // wait 10 millisec MCUCR = _BV(SM1) | _BV(SE); // power down mode, SE enables Sleep Modes sleep_cpu(); // put CPU into Power Down Sleep Mode }
void xmitCodeElement(uint16_t on_time, uint16_t off_time, uint8_t is_pwm) { // Reset the timers so they are aligned + clean timer flags TCNT0 = 0; TIFR = 0; if(is_pwm) { // Turn on PWM timer TCCR0A =_BV(COM0A0) | _BV(WGM01); TCCR0B = _BV(CS00); } else { PORTB |= _BV(IRLED); } delay_ten_us(on_time); // Turn off PWM timer TCCR0A = 0; TCCR0B = 0; PORTB &= ~_BV(IRLED); delay_ten_us(off_time); }
int main(void) { // Red-Status LED DDRB |= _BV(0); // Set PORTB pin 4 to digital output (equivalent to pinMode(0, OUTPUT)) PORTB &= ~_BV(0); // Pin 0 set to LOW (equivalent to digitalWrite(0, LOW)) /* Replace with your application code */ int i = 0; while (1) { i++; if (i == 0) PORTB |= _BV(0);// digitalWrite(4, HIGH); if (i == 2) PORTB &= ~_BV(0); // digitalWrite(4, LOW); if (i == 12) i = -1; roomba_send(162); // Virtual Wall delay_ten_us(1000); } }
uint16_t testSDCard(void) { FATFS fatfs; /* File system object */ DIR dir; /* Directory object */ FILINFO fno; /* File information object */ WORD bw, br, i; BYTE buff[64]; print("Mount a volume."); RET(); FRESULT rc = pf_mount(&fatfs); if (rc) die(rc); print("Open a test file (message.txt)."); RET(); rc = pf_open("MESSAGE.TXT"); if (rc) die(rc); print("Type the file content."); RET(); for (;;) { rc = pf_read(buff, sizeof(buff), &br); /* Read a chunk of file */ if (rc || !br) break; /* Error or end of file */ for (i = 0; i < br; i++) /* Type the data */ putchar(buff[i]); } if (rc) die(rc); #if _USE_WRITE sprintf(string,"\nOpen a file to write (write.txt).\n"); print(string); rc = pf_open("WRITE.TXT"); if (rc) die(rc); sprintf(string,"\nWrite a text data. (Hello world!)\n"); print(string); for (;;) { rc = pf_write("Hello world!\r\n", 14, &bw); if (rc || !bw) break; } if (rc) die(rc); sprintf(string,"\nTerminate the file write process.\n"); print(string); rc = pf_write(0, 0, &bw); if (rc) die(rc); #endif #if _USE_DIR print("Open root directory."); RET(); rc = pf_opendir(&dir, ""); if (rc) die(rc); print("Directory listing..."); RET(); for (;;) { rc = pf_readdir(&dir, &fno); /* Read a directory item */ if (rc || !fno.fname[0]) break; /* Error or end of dir */ if (fno.fattrib & AM_DIR) { print(" <dir> "); print(fno.fname); RET(); } else { printInt((uint8_t*)&fno.fsize, sizeof(fno.fsize)); print(fno.fname); RET(); } } if (rc) die(rc); #endif print("\nTest completed.\n"); while(1) { delay_ten_us(50000); delay_ten_us(50000); P1OUT ^= (1 << RED_LED); } return 0xaa55; }
// This function quickly pulses the visible LED (connected to PB0, pin 5) // This will indicate to the user that a code is being transmitted void quickflashLED( void ) { PORTB &= ~_BV(LED); // turn on visible LED at PB0 by pulling pin to ground delay_ten_us(3000); // 30 millisec delay PORTB |= _BV(LED); // turn off visible LED at PB0 by pulling pin to +3V }
int main(void) { uint16_t ontime, offtime; uint8_t i,j, Loop; uint8_t region = US; // by default our code is US Loop = 0; // by default we are not going to loop TCCR1 = 0; // Turn off PWM/freq gen, should be off already TCCR0A = 0; TCCR0B = 0; i = MCUSR; // Save reset reason MCUSR = 0; // clear watchdog flag WDTCR = _BV(WDCE) | _BV(WDE); // enable WDT disable WDTCR = 0; // disable WDT while we setup DDRB = _BV(LED) | _BV(IRLED); // set the visible and IR LED pins to outputs PORTB = _BV(LED) | // visible LED is off when pin is high _BV(IRLED) | // IR LED is off when pin is high _BV(REGIONSWITCH); // Turn on pullup on region switch pin // check the reset flags if (i & _BV(BORF)) { // Brownout // Flash out an error and go to sleep flashslowLEDx(2); tvbgone_sleep(); } delay_ten_us(5000); // Let everything settle for a bit // determine region if (PINB & _BV(REGIONSWITCH)) { region = US; // US } else { region = EU; } // Tell the user what region we're in - 3 is US 4 is EU quickflashLEDx(3+region); // Starting execution loop delay_ten_us(25000); // turn on watchdog timer immediately, this protects against // a 'stuck' system by resetting it wdt_enable(WDTO_8S); // 1 second long timeout do { //Execute the code at least once. If Loop is on, execute forever. // We may have different number of codes in either database if (region == US) { j = num_NAcodes; } else { j = num_EUcodes; } // for every POWER code in our collection for(i=0 ; i < j; i++) { //To keep Watchdog from resetting in middle of code. wdt_reset(); // point to next POWER code, from the right database if (region == US) { code_ptr = (PGM_P)pgm_read_word(NApowerCodes+i); } else { code_ptr = (PGM_P)pgm_read_word(EUpowerCodes+i); } // Read the carrier frequency from the first byte of code structure const uint8_t freq = pgm_read_byte(code_ptr++); // set OCR for Timer1 to output this POWER code's carrier frequency OCR0A = freq; // Get the number of pairs, the second byte from the code struct const uint8_t numpairs = pgm_read_byte(code_ptr++); // Get the number of bits we use to index into the timer table // This is the third byte of the structure const uint8_t bitcompression = pgm_read_byte(code_ptr++); // Get pointer (address in memory) to pulse-times table // The address is 16-bits (2 byte, 1 word) const PGM_P time_ptr = (PGM_P)pgm_read_word(code_ptr); code_ptr+=2; // Transmit all codeElements for this POWER code // (a codeElement is an onTime and an offTime) // transmitting onTime means pulsing the IR emitters at the carrier // frequency for the length of time specified in onTime // transmitting offTime means no output from the IR emitters for the // length of time specified in offTime // For EACH pair in this code.... for (uint8_t k=0; k<numpairs; k++) { uint8_t ti; // Read the next 'n' bits as indicated by the compression variable // The multiply by 4 because there are 2 timing numbers per pair // and each timing number is one word long, so 4 bytes total! ti = (read_bits(bitcompression)) * 4; // read the onTime and offTime from the program memory ontime = pgm_read_word(time_ptr+ti); // read word 1 - ontime offtime = pgm_read_word(time_ptr+ti+2); // read word 2 - offtime // transmit this codeElement (ontime and offtime) xmitCodeElement(ontime, offtime, (freq!=0)); } //Flush remaining bits, so that next code starts //with a fresh set of 8 bits. bitsleft_r=0; // delay 250 milliseconds before transmitting next POWER code delay_ten_us(25000); // visible indication that a code has been output. quickflashLED(); } } while (Loop == 1); // We are done, no need for a watchdog timer anymore wdt_disable(); // flash the visible LED on PB0 4 times to indicate that we're done delay_ten_us(65500); // wait maxtime delay_ten_us(65500); // wait maxtime quickflashLEDx(4); tvbgone_sleep(); }
/* Leave pin off for time (given in microseconds) */ void space(int time) { // Sends an IR space for the specified number of microseconds. // A space is no output, so the PWM output is disabled. GTCCR &= ~(_BV(COM1B0)); // turn on OC1B PWM output delay_ten_us(time / 10); }
void mark(int time) { // Sends an IR mark for the specified number of microseconds. // The mark output is modulated at the PWM frequency. GTCCR |= _BV(COM1B0); // turn on OC1B PWM output delay_ten_us(time / 10); }
int main(void) { uint8_t i, j; uint16_t ontime, offtime; TCCR1 = 0; // Turn off PWM/freq gen, should be off already TCCR0A = 0; TCCR0B = 0; i = MCUSR; // Save reset reason MCUSR = 0; // clear watchdog flag WDTCR = _BV(WDCE) | _BV(WDE); // enable WDT disable WDTCR = 0; // disable WDT while we setup DDRB = _BV(LED) | _BV(IRLED); // set the visible and IR LED pins to outputs PORTB = _BV(LED) | // visible LED is off when pin is high _BV(IRLED); // IR LED is off when pin is high // check the reset flags if (i & _BV(BORF)) { // Brownout // Flash out an error and go to sleep flashslowLEDx(2); tvbgone_sleep(); } delay_ten_us(5000); // Let everything settle for a bit // Starting execution loop // delay_ten_us(25000); // turn on watchdog timer immediately, this protects against // a 'stuck' system by resetting it wdt_enable(WDTO_8S); // 1 second long timeout for (i=0; i<1; i++) { // repeat the code twice //To keep Watchdog from resetting in middle of code. wdt_reset(); quickflashLED(); // visible indication that a code is being output uint8_t freq = pgm_read_byte(&NikonCode); // set OCR for Timer1 and Timer0 to output this POWER code's carrier frequency OCR0A = OCR0B = freq; // transmit all codeElements for this POWER code (a codeElement is an onTime and an offTime) // transmitting onTime means pulsing the IR emitters at the carrier frequency for the length of time specified in onTime // transmitting offTime means no output from the IR emitters for the length of time specified in offTime j = 0; // index into codeElements of this POWER code do { // read the onTime and offTime from the program memory ontime = pgm_read_word(&NikonCode+(j*4)+1); offtime = pgm_read_word(&NikonCode+(j*4)+3); xmitCodeElement(ontime, offtime, 1); // transmit this codeElement (ontime and offtime) j++; } while ( offtime != 0 ); // offTime = 0 signifies last codeElement for a POWER code PORTB |= _BV(IRLED); // turn off IR LED // delay 250 milliseconds before transmitting next POWER code delay_ten_us(25000); } // We are done, no need for a watchdog timer anymore wdt_disable(); // flash the visible LED on PB0 4 times to indicate that we're done delay_ten_us(65500); // wait maxtime quickflashLED4x(); // Shut down everything and put the CPU to sleep TCCR1 = 0; // turn off frequency generator (should be off already) TCCR0B = 0; PORTB |= _BV(LED); // turn on the button pullup, turn off visible LED PORTB |= _BV(IRLED); // turn off IR LED delay_ten_us(1000); // wait 10 millisec second MCUCR = _BV(SM1) | _BV(SE); // power down mode, SE=1 (bit 5) -- enables Sleep Modes sleep_cpu(); // put CPU inteo Power Down Sleep Mode }