Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- manitou
- Date:
- 2016-04-13
- Revision:
- 0:785739d5a30a
- Child:
- 1:af81e02b8c7b
File content as of revision 0:785739d5a30a:
/*
IRtest
hack of maple version
http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
use PWM to generate mark/space at 38Khz
IR LED xmit pin to 100ohm to +IR - to grnd (short/flat)
use timer 50us to count mark/space on input
is it possible to run both xmit and recv?
*/
#include "mbed.h"
#include "IRremote.h"
Ticker ticker;
// K64F pins
#define RecvPin D7
#define PWMPin D6
#define TestPin D13
PwmOut pwm(PWMPin);
DigitalIn recvpin(RecvPin);
DigitalOut testpin(TestPin); // jumper to D8 for test
DigitalOut myled(LED1);
volatile unsigned long myticks;
int rawbuf[RAWBUF], rawlen;
uint8_t rcvstate;
int results_decode_type; // NEC, SONY, RC5, UNKNOWN
unsigned long results_value;
int results_bits; // Number of bits in decoded value
void timer_ISR() {
// interrupt every 50us
uint8_t irdata = recvpin; // read IR sensor
myticks++;
if (rawlen >= RAWBUF) {
// Buffer overflow
rcvstate = STATE_STOP;
}
switch(rcvstate) {
case STATE_IDLE: // In the middle of a gap
if (irdata == MARK) {
if (myticks < GAP_TICKS) {
// Not big enough to be a gap.
myticks = 0;
}
else {
// gap just ended, record duration and start recording transmission
rawlen = 0;
rawbuf[rawlen++] = myticks;
myticks = 0;
rcvstate = STATE_MARK;
}
}
break;
case STATE_MARK: // timing MARK
if (irdata == SPACE) { // MARK ended, record time
rawbuf[rawlen++] = myticks;
myticks = 0;
rcvstate = STATE_SPACE;
}
break;
case STATE_SPACE: // timing SPACE
if (irdata == MARK) { // SPACE just ended, record it
rawbuf[rawlen++] = myticks;
myticks = 0;
rcvstate = STATE_MARK;
}
else { // SPACE
if (myticks > GAP_TICKS) {
// big SPACE, indicates gap between codes
// Mark current code as ready for processing
// Switch to STOP
// Don't reset timer; keep counting space width
rcvstate = STATE_STOP;
}
}
break;
case STATE_STOP: // waiting, measuring gap
if (irdata == MARK) { // reset gap timer
myticks = 0;
}
break;
}
}
// set up recv timer
void enableIRIn(){
ticker.attach_us(&timer_ISR,50);
rcvstate = STATE_IDLE;
rawlen = 0;
}
void irrecv_resume() {
rcvstate = STATE_IDLE;
rawlen = 0;
}
long decodeSony() {
long data = 0;
if (rawlen < 2 * SONY_BITS + 2) {
return ERR;
}
int offset = 1; // Skip first space
// Initial mark
if (!MATCH_MARK(rawbuf[offset], SONY_HDR_MARK)) {
return ERR;
}
offset++;
while (offset + 1 < rawlen) {
if (!MATCH_SPACE(rawbuf[offset], SONY_HDR_SPACE)) {
break;
}
offset++;
if (MATCH_MARK(rawbuf[offset], SONY_ONE_MARK)) {
data = (data << 1) | 1;
}
else if (MATCH_MARK(rawbuf[offset], SONY_ZERO_MARK)) {
data <<= 1;
}
else {
return ERR;
}
offset++;
}
// Success
results_bits = (offset - 1) / 2;
if (results_bits < 12) {
results_bits = 0;
return ERR;
}
results_value = data;
results_decode_type = SONY;
return DECODED;
}
void enableIROut(int khz) {
int freq = 1000 * khz;
pwm.period(1./freq);
pwm.write(0); // start PWM with low
}
void mark(int time) {
pwm.write(0.5); // PWM on
testpin=0; // test invert
wait_us(time);
}
void space(int time) {
pwm.write(0); // off
testpin=1;
wait_us(time);
}
void sendSony(unsigned long data, int nbits) {
enableIROut(40);
mark(SONY_HDR_MARK);
space(SONY_HDR_SPACE);
data = data << (32 - nbits);
for (int i = 0; i < nbits; i++) {
if (data & TOPBIT) {
mark(SONY_ONE_MARK);
space(SONY_HDR_SPACE);
}
else {
mark(SONY_ZERO_MARK);
space(SONY_HDR_SPACE);
}
data <<= 1;
}
}
void sendRaw(unsigned int buf[], int len, int khz)
{
enableIROut(khz);
for (int i = 0; i < len; i++) {
if (i & 1) {
space(buf[i]);
}
else {
mark(buf[i]);
}
}
space(0); // Just to be sure
}
main() {
long sonycmd[] = {0xA9A,0x91A,0x61A}; // power 0 7
pwm.period(1.);
pwm.write(0); // when no PWM, want pin low
enableIRIn();
while(true) {
printf("xmit\n");
myled=1;
sendSony(sonycmd[0],SONY_BITS);
myled=0;
wait(.006); // let gap time grow
if (rcvstate == STATE_STOP) {
if (decodeSony() ) {
printf("sony decoded. value %0x %d bits\n",results_value, results_bits);
}
printf("rawlen %d\n",rawlen);
for (int i=0; i < rawlen; i++) {
if (i%2) printf(" ");
printf("%d\n",rawbuf[i]*USECPERTICK);
}
irrecv_resume();
}
wait(2.0);
}
}