In the first and second part of this series I introduced my idea’s about the IR project.
I also showed some basic receiving, and even receiving over the air.
What was left out, was the sending part.
Today I found some time to get a sending setup together.
Here’s the setup:
- A Jeelink containing a sketch which translates serial commands to IR codes and sends them over the air;
- A Jeenode on the receiving side, which receives the IR commands and sends them out to an IR led;
- A python script to send commands to the serial port, to create a basic zapping demo.
Here’s a little video demonstrating the sketches and python script below:
The Jeelink has the following sketch:
/*
* mdRFReceive - Generic home automation RF12 receiver.
* Version 0.1 June, 2010
* Copyright 2010 Maarten Damen
* http://www.maartendamen.com
*/
#include <Ports.h>
#include <RF12.h>
#define MAX_STRING_LEN 20
byte needToSend;
long unsigned int sendbuf;
char buffer[MAX_STRING_LEN];
int bufferIndex = 0;
void setup() {
Serial.begin(57600);
rf12_config();
}
static void sendIR(long unsigned int code) {
sendbuf = code;
needToSend = 1;
}
char* subStr (char* str, char *delim, int index) {
char *act, *sub, *ptr;
char output;
static char copy[MAX_STRING_LEN];
int i;
// Since strtok consumes the first arg, make a copy
strcpy(copy, str);
for (i = 1, act = copy; i <= index; i++, act = NULL) {
sub = strtok_r(act, delim, &ptr);
if (sub == NULL) break;
}
return sub;
}
unsigned long long conv64(char* str)
{
unsigned long long res = 0;
// remove 0x or 0X part
if((strstr(str, "0x") == str) || (strstr(str, "0X") == str))
str += 2;
// do the conversion...
for(; *str != 0; str++)
{
// multiply by 16 (remember, hexadecimal == base 16)
res <<= 4;
if(strchr("0123456789", *str) != NULL) // if within 0-9...
res |= *str - '0';
else if(strchr("ABCDEF", *str) != NULL) // if within A-F...
res |= *str + 10 - 'A';
else if(strchr("abcdef", *str) != NULL) // if within a-f...
res |= *str + 10 - 'a';
else
{
res >>= 4;
break;
}
}
return res;
}
static void handleInput (char* command, char* argument) {
if (strcmp(command, "send_tv") == 0)
{
long unsigned int test = conv64(argument);
sendIR(test);
}
}
void loop() {
if (Serial.available())
{
char ch = Serial.read();
if (ch == '\n')
{
bufferIndex = 0;
handleInput(subStr(buffer, " ", 1), subStr(buffer, " ", 2));
} else {
buffer[bufferIndex++] = ch;
}
}
if (rf12_recvDone() && rf12_crc == 0) {
byte n = rf12_len;
Serial.println("Packet CRC OK");
Serial.print((int) rf12_hdr);
for (byte i = 0; i < n; i++) {
Serial.print(' ');
Serial.print((int) rf12_data[i]);
}
Serial.println();
}
if (needToSend && rf12_canSend()) {
needToSend = 0;
rf12_sendStart(0, &sendbuf, sizeof sendbuf);
}
}
The Jeenode has the following receiving sketch:
/*
* mdIR - IR interface for home automation.
* Version 0.1 May, 2010
* Copyright 2010 Maarten Damen
* http://www.maartendamen.com
*/
#include <RF12.h>
#include <Ports.h>
#include <IRremote.h>
IRsend irsend;
int RECV_PIN = 4;
IRrecv irrecv(RECV_PIN);
MilliTimer sendTimer;
byte needToSend;
decode_results results;
long unsigned int sendbuf;
long unsigned int received;
struct {
byte decode; // IR decode
} payload;
void setup () {
Serial.begin(57600);
Serial.println(57600);
Serial.println("mdIR started...");
rf12_config();
irrecv.enableIRIn(); // Start the IR receiver
}
void loop () {
if (irrecv.decode(&results)) {
needToSend = 1;
sendbuf = results.value;
Serial.println(results.value);
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
/* TODO: rf12_canSend doesn't work if I remove this... (needs to check incoming packets?) */
if (rf12_recvDone() && rf12_crc == 0 && (int) rf12_hdr == 10) {
byte n = rf12_len;
Serial.println("Packet CRC OK");
Serial.println((int) n);
for (byte i = 0; i < n; i++) {
Serial.print(' ');
Serial.print((int) rf12_data[i]);
}
Serial.println();
received = ( ((long) rf12_data[3] << 24)
+ ((long) rf12_data[2] << 16)
+ ((long) rf12_data[1] << 8)
+ ((long) rf12_data[0] ) );
irsend.sendSamsung(received, 32);
/* Re-enable receiving mode */
irrecv.enableIRIn();
Serial.println();
}
if (needToSend && rf12_canSend()) {
needToSend = 0;
Serial.println("need to send");
rf12_sendStart(0, &sendbuf, sizeof sendbuf);
}
}
The python scripts looks like this:
from twisted.internet.serialport import SerialPort
import sys
from twisted.protocols import basic
if sys.platform == 'win32':
from twisted.internet import win32eventreactor
win32eventreactor.install()
from twisted.internet import reactor
class IRProtocol(basic.LineReceiver):
def __init__(self):
# Power on the tv
reactor.callLater(10.0, self.send_tv, "0xE0E040BF")
# Zap a bit
reactor.callLater(15.0, self.send_tv, "0xE0E020DF")
reactor.callLater(20.0, self.send_tv, "0xE0E0A05F")
reactor.callLater(25.0, self.send_tv, "0xE0E0609F")
reactor.callLater(30.0, self.send_tv, "0xE0E010EF")
reactor.callLater(35.0, self.send_tv, "0xE0E0906F")
def lineReceived(self, line):
""" Do nothing with received lines yet """
def send_tv(self, command):
"""
Send's an IR command.
"""
self.transport.write('send_tv ' + command + '\n')
SerialPort(IRProtocol(), 6 , reactor, '57600')
reactor.run()
5 thoughts on “Jeenode infrared project part 3: sending test”
Comments are closed.
Recent Posts
The time is finally come! Samsung have released their Galaxy Watch 4 series of watches. It features Google Wear OS 3. and it comes in two models, being the standard model and the watch 4 classic. In...
Microsoft 365 Defender cross check with on-premises Active Directory
Recently I was reviewing the new Microsoft 365 Defender portal and I noticed that a few endpoints were missing from the device inventory. This got me thinking that it would be great if I could...

Hi,
I’m trying to send IRcodes to my Samsung, and have some problems.
In your code you have
\irsend.sendSamsung(received, 32);\
Where can I find that function?
Thanks a lot,
Ribeiro Santos
Simple 🙂
Just add in IRemote.cpp
void IRsend::sendSamsung(unsigned long data, int nbits)
{
enableIROut(38);
mark(SAMSUNG_HDR_MARK);
space(SAMSUNG_HDR_SPACE);
for (int i = 0; i < nbits; i++) {
if (data & TOPBIT) {
mark(SAMSUNG_BIT_MARK);
space(SAMSUNG_ONE_SPACE);
}
else {
mark(SAMSUNG_BIT_MARK);
space(SAMSUNG_ZERO_SPACE);
}
data <<= 1;
}
mark(SAMSUNG_BIT_MARK);
space(0);
}
Add in IRemote.h
class IRsend
{
public:
IRsend() {}
void sendNEC(unsigned long data, int nbits);
//add this line
void sendSamsung(unsigned long data, int nbits);
After that, just use, in your sketch;
irsend.sendSamsung(
, 32);next channel:
irsend.sendSamsung(0xE0E048B7, 32);