Lightweight DTLS reverse proxy server based on tinydtls and libev.
https://github.com/julznc/dtlsproxy
Wednesday, September 13, 2017
Saturday, May 6, 2017
ATtiny IR Remote
ATtiny2313 Infrared Sender
parts:




avr-gcc (main.c) code:
References:
ESP8266 IR Remote
z3t0/Arduino-IRremote
ATtiny Low Power
parts:
- ATtiny2313 @4MHz (internal oscillator)
- IR LED (series with 220-ohm resistor)
- Tact switches
- 3.7V lithium ion battery & Capacitor




avr-gcc (main.c) code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* http://projectproto.blogspot.com/2017/05/attiny-ir-remote.html | |
*/ | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#include <avr/sleep.h> | |
#include <util/delay.h> | |
// led (OC0B) pin | |
#define IRLED_ENABLE() DDRD |= _BV(DDD5); PORTD &= ~_BV(PD5); | |
#define IRLED_DISABLE() DDRD &= ~_BV(DDD5); | |
// push buttons | |
#define POWER_BTN _BV(PB3) | |
#define FUNCTION_BTN _BV(PB2) | |
#define VOLUP_BTN _BV(PB4) | |
#define VOLDOWN_BTN _BV(PB5) | |
#define TUNEUP_BTN _BV(PB7) | |
#define TUNEDOWN_BTN _BV(PB6) | |
#define ALL_BTN (POWER_BTN|FUNCTION_BTN|VOLUP_BTN|VOLDOWN_BTN|TUNEUP_BTN|TUNEDOWN_BTN) | |
#define TIMER_ENABLE_PWM() (TCCR0A |= _BV(COM0B1)) | |
#define TIMER_DISABLE_PWM() (TCCR0A &= ~(_BV(COM0B1))) | |
#define TIMER_CONFIG_KHZ(val) ({ \ | |
const uint8_t pwmval = F_CPU / 2000 / (val); \ | |
TCCR0A = _BV(WGM00); \ | |
TCCR0B = _BV(WGM02) | _BV(CS00); \ | |
OCR0A = pwmval; \ | |
OCR0B = pwmval / 3; \ | |
}) | |
#define MARK(us) TIMER_ENABLE_PWM(); _delay_us(us) | |
#define SPACE(us) TIMER_DISABLE_PWM(); _delay_us(us) | |
#define SONY_HDR_MARK 2400 | |
#define SONY_HDR_SPACE 600 | |
#define SONY_ONE_MARK 1200 | |
#define SONY_ZERO_MARK 600 | |
//http://elektrolab.wz.cz/katalog/samsung_protocol.pdf | |
#define SAMSUNG_HDR_MARK 4500 | |
#define SAMSUNG_HDR_SPACE 4500 | |
#define SAMSUNG_BIT_MARK 560 | |
#define SAMSUNG_ONE_SPACE 1690 | |
#define SAMSUNG_ZERO_SPACE 560 | |
void enableIROut (int khz) | |
{ | |
IRLED_ENABLE(); | |
TIMER_CONFIG_KHZ(khz); | |
} | |
uint32_t reverseBits(uint32_t input, uint8_t nbits) { | |
uint32_t output = input; | |
for (uint8_t i = 1; i < nbits; i++) { | |
output <<= 1; | |
input >>= 1; | |
output |= (input & 1); | |
} | |
return output; | |
} | |
uint32_t encodeSony (uint8_t nbits, uint8_t command, | |
uint8_t address, uint8_t extended) | |
{ | |
uint32_t result = 0; | |
switch (nbits) { | |
case 12: // 5 address bits. | |
result = address & 0x1F; | |
break; | |
case 15: // 8 address bits. | |
result = address & 0xFF; | |
break; | |
case 20: // 5 address bits, 8 extended bits. | |
result = address & 0x1F; | |
result |= (extended & 0xFF) << 5; | |
break; | |
default: | |
return 0; | |
} | |
result = (result << 7) | (command & 0x7F); | |
return reverseBits(result, nbits); | |
} | |
void sendSony (uint32_t data, int nbits) | |
{ | |
// Set IR carrier frequency | |
enableIROut(40); | |
// Header | |
MARK(SONY_HDR_MARK); | |
SPACE(SONY_HDR_SPACE); | |
// Data | |
for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) { | |
if (data & mask) { | |
MARK(SONY_ONE_MARK); | |
SPACE(SONY_HDR_SPACE); | |
} else { | |
MARK(SONY_ZERO_MARK); | |
SPACE(SONY_HDR_SPACE); | |
} | |
} | |
} | |
void sendSamsung (uint32_t data, int nbits) | |
{ | |
// Set IR carrier frequency | |
enableIROut(38); | |
// Header | |
MARK(SAMSUNG_HDR_MARK); | |
SPACE(SAMSUNG_HDR_SPACE); | |
// Data | |
for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) { | |
if (data & mask) { | |
MARK(SAMSUNG_BIT_MARK); | |
SPACE(SAMSUNG_ONE_SPACE); | |
} else { | |
MARK(SAMSUNG_BIT_MARK); | |
SPACE(SAMSUNG_ZERO_SPACE); | |
} | |
} | |
// Footer | |
MARK(SAMSUNG_BIT_MARK); | |
SPACE(0); // Always end with the LED off | |
} | |
void enterSleep(void) | |
{ | |
IRLED_DISABLE(); | |
// Enable Pin Change Interrupts on all buttons | |
GIMSK |= _BV(PCIE); | |
PCMSK |= ALL_BTN; | |
sleep_enable(); | |
sei(); // Enable interrupts | |
sleep_cpu(); | |
} | |
ISR(PCINT_vect) { | |
cli(); // Disable interrupts | |
PCMSK &= ~ALL_BTN; // clear interrupt flags | |
sleep_disable(); | |
_delay_ms(1); | |
switch ( (~PINB) & ALL_BTN ) | |
{ | |
#if 1 // sony dvd | |
case POWER_BTN: | |
sendSony(encodeSony(15, 21, 80, 0), 15); // on/off | |
break; | |
case FUNCTION_BTN: | |
sendSony(encodeSony(15, 105, 208, 0), 15); // source | |
break; | |
case VOLUP_BTN: | |
sendSony(encodeSony(15, 18, 80, 0), 15); // volume + | |
break; | |
case VOLDOWN_BTN: | |
sendSony(encodeSony(15, 19, 80, 0), 15); // volume - | |
break; | |
case TUNEUP_BTN: | |
sendSony(encodeSony(20, 52, 16, 16), 20); // tune + | |
break; | |
case TUNEDOWN_BTN: | |
sendSony(encodeSony(20, 51, 16, 16), 20); // tune - | |
break; | |
#else // samsung tv | |
// https://github.com/lepiaf/IR-Remote-Code | |
case POWER_BTN: | |
sendSamsung(0xE0E040BF, 32); // on/off | |
break; | |
case FUNCTION_BTN: | |
sendSamsung(0xE0E0807F, 32); // source | |
break; | |
case VOLUP_BTN: | |
sendSamsung(0xE0E0E01F, 32); // volume + | |
break; | |
case VOLDOWN_BTN: | |
sendSamsung(0xE0E0D02F, 32); // volume - | |
break; | |
case TUNEUP_BTN: | |
sendSamsung(0xE0E048B7, 32); // channel + | |
break; | |
case TUNEDOWN_BTN: | |
sendSamsung(0xE0E008F7, 32); // channel - | |
break; | |
#endif | |
} | |
} | |
int main(void) | |
{ | |
// analog comparator off | |
ACSR &= ~_BV(ACD); | |
DIDR |= _BV(AIN1D) | _BV(AIN0D); | |
// initially all input pins with pull-up's | |
DDRA = DDRB = DDRD = 0; | |
PORTA = PORTB = PORTD = 0xFF; | |
IRLED_ENABLE(); | |
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | |
while(1) { | |
enterSleep(); | |
} | |
} |
References:
ESP8266 IR Remote
z3t0/Arduino-IRremote
ATtiny Low Power
Friday, May 5, 2017
ESP8266 IR Remote
Control your appliances (e.g. TV and AV systems) via WiFi+IR.

Arduino code:
References:
markszabo/IRremoteESP8266
Sony IR codes
Sony SIRC protocol

Arduino code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <WiFiClient.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <IRremoteESP8266.h> | |
IRsend irsend( 14 /*GPIO pin*/); | |
ESP8266WebServer server(80); | |
const char* ssid = "........"; | |
const char* password = "........"; | |
// soft access point (as backup) | |
static const char *softAPssid = "ir-remote"; | |
static const char *softAPpassword = "12345678"; | |
static const char *indexhtml = "<html>\n" | |
"<head>\n" | |
"<title>IR remote</title>\n" | |
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" | |
"</head>\n" | |
"<style media=\"screen\" type=\"text/css\">\n" | |
"table{width:100%;}\n" | |
"button{display: block; width:96%; padding:12px; margin: 4px; font-weight:bold; font-size:1.5em;}\n" | |
"</style>\n" | |
"<body>\n" | |
"<script type=\"text/javascript\">\n" | |
"function req(cmd)\n" | |
"{ var xmlHttp = new XMLHttpRequest();\n" | |
"console.log(cmd);\n" | |
"xmlHttp.onreadystatechange = function(){}\n" | |
"xmlHttp.open(\"GET\", cmd, true);xmlHttp.send(null); }\n" | |
"var intervals = {};\n" | |
"function pressed(cmd){ req(cmd); intervals[cmd] = setInterval(function() { req(cmd); }, 250); }\n" | |
"function unpressed(){for (var cmd in intervals){ clearInterval(intervals[cmd]); } }\n" | |
"</script>\n" | |
"<h2>Sony AV System Remote</h2>\n" | |
"<table>\n" | |
"<tr><td><button onmousedown=\"req('power')\">POWER</button></td>\n" | |
"<td><button onmousedown=\"req('func')\">FUNC</button></td></tr>\n" | |
"<tr><td><button onmousedown=\"pressed('volup')\" ontouchstart=\"pressed('volup')\" onmouseup=\"unpressed()\" ontouchend=\"unpressed()\">VOL+</button></td>\n" | |
"<td><button onmousedown=\"pressed('tuneup')\" ontouchstart=\"pressed('tuneup')\" onmouseup=\"unpressed()\" ontouchend=\"unpressed()\">TUNE+</button></td></tr>\n" | |
"<tr><td><button onmousedown=\"pressed('voldown')\" ontouchstart=\"pressed('voldown')\" onmouseup=\"unpressed()\" ontouchend=\"unpressed()\">VOL-</button></td>\n" | |
"<td><button onmousedown=\"pressed('tunedown')\" ontouchstart=\"pressed('tunedown')\" onmouseup=\"unpressed()\" ontouchend=\"unpressed()\">TUNE-</button></td></tr>\n" | |
"</table>\n" | |
"</body>\n" | |
"</html>\n"; | |
void handleRoot() { | |
server.send(200, "text/html", indexhtml); | |
} | |
void handlePower() { | |
Serial.println("power"); | |
irsend.sendSony(irsend.encodeSony(15, 21, 80), 15, 2); | |
server.send(200, "text/plain", "power"); | |
} | |
void handleFunc() { | |
Serial.println("func"); | |
irsend.sendSony(irsend.encodeSony(15, 105, 208), 15, 2); | |
server.send(200, "text/plain", "func"); | |
} | |
void handleVolup() { | |
Serial.println("volup"); | |
irsend.sendSony(irsend.encodeSony(15, 18, 80), 15, 2); | |
server.send(200, "text/plain", "volup"); | |
} | |
void handleVoldown() { | |
Serial.println("voldown"); | |
irsend.sendSony(irsend.encodeSony(15, 19, 80), 15, 2); | |
server.send(200, "text/plain", "voldown"); | |
} | |
void handleTuneup() { | |
Serial.println("tuneup"); | |
irsend.sendSony(irsend.encodeSony(20, 52, 16, 16), 20, 2); | |
server.send(200, "text/plain", "tuneup"); | |
} | |
void handleTunedown() { | |
Serial.println("tunedown"); | |
irsend.sendSony(irsend.encodeSony(20, 51, 16, 16), 20, 2); | |
server.send(200, "text/plain", "down"); | |
} | |
void handleNotFound(){ | |
server.send(404, "text/plain", "Not Found"); | |
} | |
void setup() | |
{ | |
Serial.begin(115200); | |
WiFi.begin(ssid, password); | |
WiFi.softAP(softAPssid, softAPpassword); | |
irsend.begin(); | |
// Wait for connection | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.print("Connected to "); | |
Serial.println(ssid); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
Serial.print("Soft AP: "); | |
Serial.println(softAPssid); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.softAPIP()); | |
if (MDNS.begin("irremote")) { | |
Serial.println("MDNS responder started"); | |
} | |
server.on("/", handleRoot); | |
server.on("/power", handlePower); | |
server.on("/func", handleFunc); | |
server.on("/volup", handleVolup); | |
server.on("/voldown", handleVoldown); | |
server.on("/tuneup", handleTuneup); | |
server.on("/tunedown", handleTunedown); | |
server.onNotFound(handleNotFound); | |
server.begin(); | |
Serial.println("HTTP server started"); | |
} | |
void loop(void){ | |
server.handleClient(); | |
} |
References:
markszabo/IRremoteESP8266
Sony IR codes
Sony SIRC protocol
Sunday, January 29, 2017
WiFi RGB Matrix
Here's a DIY flexible 36x8 RGB-LED-matrix controlled via WiFi connection using an ESP8266 module.
Arduino Code: julznc/wifi_rgb_matrix
Assembly:
References:
NeoPixelBus - for interfacing WS2812 LEDs to ESP8266 controller
Adafruit-GFX-Library - with font library for displaying texts
LED Matrix Studio - for creating bitmap images
Arduino Code: julznc/wifi_rgb_matrix
Assembly:
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
References:
NeoPixelBus - for interfacing WS2812 LEDs to ESP8266 controller
Adafruit-GFX-Library - with font library for displaying texts
LED Matrix Studio - for creating bitmap images
Subscribe to:
Posts (Atom)