Hardware components | ||||||
| × | 3 | ||||
![]() |
| × | 1 | |||
Hand tools and fabrication machines | ||||||
![]() |
|
Imported from: https://www.hwhardsoft.de/2017/08/17/iot-meets-stretchlimousine/
The ideaSometimes ago a customer asked us for help with the interior control of his Lincoln stretch limousine. The old solution was not so nice, there was no comfortable solution for the driver to control the lighting in the passenger cabin and he wants a remote control via mobile app in the future. Our Solution fulfills the following requirements:
- control via touch screens with modern GUI
- 2nd touch screen for the driver
- communication of all components via WiFi
- rugged design
- simple to extend
We've used the ESP8266 - especially the Wemos D1 mini - for our solution. These modules comes with integrated USB Module (makes programming easy), are supported by a big community, they need no boot time and are very simple and rugged. We've used the Arduino IDE for the programming of the firmware. Only the control board and touch screens are new - the old relay boards are used for this new solution again:
For the touch panels we've used Nextion touch screens. All pictures and other data of the GUI is stored in the Nextion touch itself. It's very easy to connect these touch screens to a microcontroller (in our case Wemos D1 mini too) via the UART.
Both touch screens are connected to self made panel boards equipped with WEMOS D1. The panel board send data of touch events via UDP to the control board. The control board send the status of all switches, temperatures and the level of the fan via UDP back. These status protocols take care that both touch screens and later the APP shows the same values...
All light effects are made with RGB led stripes connected to LED controllers. The control board can send infrared commands to control the color and brightness of the RGB stripes. Furthermore a fiber based "starry sky" is integrated in the ceiling. This starry sky is controlled by an special unit. We can control this unit via a RF remote control on the control board
Pictures:/*
* Mikrocontroller fr Marwinski Controlboard
* Version 1.0
* Copyright (C) 2017 Hartmut Wendt www.hwhardsoft.de
*
*/
#include <Wire.h>
#include "IRLibAll.h"
IRsend mySender;
//#define _debug
//char inputString[101]; // a string to hold incoming data
String inputString =""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup() {
//PORTs
DDRB = B00111111;
DDRC = B00111111;
DDRD = B11111100;
Serial.begin(9600);
// reserve 100 bytes for the inputString:
//inputString.reserve(100);
delay(200);
Wire.setClock(100000);
init_MCP23016();
delay(200);
}
void loop() {
byte i1;
byte i2;
byte i3;
long l1;
if (stringComplete) {
#ifdef _debug
Serial.println(inputString);
#endif
// Auf bestimmte Befehle reagieren
// alle IOs setzen, inklusive Portexpander
i1 = inputString.indexOf("IO=");
if (i1 < 255)
{
#ifdef _debug
Serial.println("IO=");
Serial.println(i1);
#endif
// setze Ausgnge PortB:
PORTB = StrToHex(inputString.substring(i1+3,i1+5),3);
#ifdef _debug
Serial.print("PortB:");
Serial.println(StrToHex(inputString.substring(i1+3,i1+5),3));
#endif
// setze Ausgnge PortC:
PORTC = StrToHex(inputString.substring(i1+5,i1+7),3);
#ifdef _debug
Serial.print("PortC:");
Serial.println(StrToHex(inputString.substring(i1+5,i1+7),3));
#endif
// setze Ausgnge PORTD
i2 = StrToHex(inputString.substring(i1+7,i1+9),3);
i2 &= B11110100;
#ifdef _debug
Serial.print("PortD:");
Serial.println(i2);
#endif
PORTD &= B00001011;
PORTD |= i2;
// setze Ausgnge Portexpander MCP23016:
i2 = StrToHex(inputString.substring(i1+9,i1+11),3);
i3 = StrToHex(inputString.substring(i1+11,i1+13),3);
#ifdef _debug
Serial.print("GP0:");
Serial.print(i2);
Serial.print(" GP1:");
Serial.println(i3);
#endif
write_MCP23016(i2,i3);
}
// Auf bestimmte Befehle reagieren
// Befehl Fernbedienung senden
i1 = inputString.indexOf("IR=");
if (i1 < 255)
{
#ifdef _debug
Serial.println("IR");
Serial.println(i1);
Serial.println(inputString.substring(i1+3,i1+11));
#endif
l1 = StrToHex(inputString.substring(i1+3,i1+11),9);
mySender.send(NEC,l1, 32);
}
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
/*
* Init the MCP23016 port expander via I2C
* set all port as output
*/
void init_MCP23016() {
Wire.begin();
Wire.beginTransmission(0x20); // set mcp23016 output
Wire.write(0x06);
Wire.write(0x00); // DDR Port0 all output
Wire.write(0x00); // DDR Port1 all output
Wire.endTransmission();
}
/*
* Set the GPIOs of port GP0 to the value of b1
* Set the GPIOs of port GP1 to the value of b2
*/
void write_MCP23016(byte b1, byte b2) {
Wire.beginTransmission(0x20); // set mcp23016 for all output
Wire.write(0x00); // begin here
Wire.write(b1);
Wire.write(b2);
Wire.endTransmission();
}
/*
byte StrToHex(String str)
{
char ConvByte[12];
str.toCharArray(ConvByte, 3);
return (byte) strtol(ConvByte, NULL, 16);
}
*/
unsigned long StrToHex(String str, byte digits)
{
char ConvByte[10];
str.toCharArray(ConvByte, digits);
return (unsigned long) strtol(ConvByte, NULL, 16);
}
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <OneWire.h>
#include <SoftwareSerial.h>
// enable debug outputs via serial Port 1 (USB)
#define _debug
// Portkonfiguration
//#define LEDBL 2 //interne blaue LED an GPIO2 des Wemos
#define LEDRT 14 //rote LED an GPIO5 (D1) des Wemos
// Port B
#define REL_VI_ON_OFF 0x01
#define CEILING_MINUS 0x02
#define CEILING_F 0x04
#define CEILING_PLUS 0x08
// Port C
#define BAR_PLUS 0x01
#define FlOOR_MINUS 0x02
#define FlOOR_F 0x04
#define FlOOR_PLUS 0x08
// Port D
#define REL_I_ON_OFF 0x04
#define REL_II_ON_OFF 0x10
#define REL_III_ON_OFF 0x20
#define REL_IV_ON_OFF 0x40
#define REL_V_ON_OFF 0x80
// MCP_GP0
#define STARS_UP 0x01
#define STARS_DWN 0x02
#define STARS_SQUARE 0x04
#define STARS_LOCK 0x08
#define REL_WALL_UP 0x10
#define REL_WALL_DWN 0x20
#define IN_DOOR_SW 0x40
#define REL_G_LIGHT 0x80
// MCP_GP1
#define REL_FAN_I 0x01
#define REL_FAN_II 0x02
#define REL_FAN_III 0x04
#define REL_CLIMA 0x08
#define REL_HEATING 0x10
#define REL_INTERCOM 0x80
#define Timeout_wall_relay 50
#define Timeout_stars_relay 5
#define Timeout_buttons_blocked 7
#define Timeout_dimmer_blocked 14
SoftwareSerial ESPserial(12, 13); // RX (D6) | TX (D7)
// Name und Passwort des Access Points
#define SSID "xxxxxx"
#define PASSWORD "xxxxx"
// Der Server nimmt Verbindungen auf diesem Port an
#define PORT 5444
#define IP_BROADCAST "192.168.0.255"
WiFiUDP udpServer;
#define WIFICLIENT_MAX_PACKET_SIZE 100
// Puffer fr hereinkommende UDP Nachrichten
char udp_buffer[WIFICLIENT_MAX_PACKET_SIZE+1];
// OneWire DS18S20, DS18B20, DS1822 Temperature sensor
OneWire ds(2); // on pin D4 (a 4.7K resistor is necessary)
float celsius; // Ist Temperatur
// Variables
byte PORTB = 0x00;
byte PORTC = 0x00;
byte PORTD = 0x00;
byte MCP_GP0 = 0x00;
byte MCP_GP1 = 0x00;
int soll_temperatur=21; //Soll Temperatur
byte bscheduler = 0;
byte sw_status0 = 0; // Schalterzustnde fr Synchronisation
byte sw_status1 = 0; // Schalterzustnde fr Synchronisation
byte fan_status = 0; // Status Geblse
char *test;
int TMO_WALL=0; // Timeout Trennwand
int TMO_STARS=0; // Timeout FB Sternenhimmel
int TMO_BUTTONS=0; // Timeout fr restliche Button
int FB_mode=0; // Zaehler Mode Fernbedienung M1-6, P1 - P8
byte mood_mode=0;
/** Wird beim Start einmal ausgefhrt */
void setup()
{
// LED blau aus
// pinMode(LEDBL, OUTPUT);
// digitalWrite(LEDBL, HIGH);
// LED rot aus
pinMode(LEDRT, OUTPUT);
digitalWrite(LEDRT, LOW);
// Seriellen Port 2 initialisieren
ESPserial.begin(9600); // Start the software serial for communication with the ESP8266
// Gib dem seriellen Port Monitor von der Arduino
// IDE ein bisschen Zeit.
#ifdef _debug
Serial.begin(9600); // Seriellen Port1 (USB) fr Debugging initialisieren.
#endif
delay(250);
// Benutze einen externen AP
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASSWORD);
// UDP Server starten
udpServer.begin(PORT);
}
/** Hauptschleife, wird wiederholt ausgefhrt. */
void loop()
{
process_incoming_udp();
check_ap_connection();
switch(bscheduler)
{
// Temperatur abfragen
case 0:
read_temperature();
break;
// Heizungssteuerung
case 6:
clima_control();
break;
// Statusmeldung (Temperaturen & Lfter senden)
case 3:
udp_message_status1();
break;
// Statusmeldung (Schalterzustnde senden)
case 7:
udp_message_status2();
break;
// Schalter bearbeiten
case 8:
switches();
break;
// Alle Ports am uC und I2C Expander setzen
case 9:
transmit_cmd_ports();
break;
}
bscheduler++;
if (bscheduler > 9) bscheduler = 0;
// Timeouts
// Timeout Trennwand
if (TMO_WALL) TMO_WALL--;
if (TMO_WALL == 0) {
// Motorrelais ausschalten
MCP_GP0 &= ~(REL_WALL_UP + REL_WALL_DWN);
}
// Timeout FB Sternenhimmel
if (TMO_STARS) TMO_STARS--;
if (TMO_STARS == 0) {
// Relais fr FB-Tasten ausschalten
MCP_GP0 &= ~(STARS_UP + STARS_DWN + STARS_LOCK + STARS_SQUARE);
}
// Timeout Tasten blockieren um Doppelbedienung zu vermeiden
if (TMO_BUTTONS) TMO_BUTTONS--;
if (TMO_BUTTONS == 0) {
PORTB &= ~CEILING_PLUS;
PORTB &= ~CEILING_MINUS;
}
delay(100);
}
/** Empfange UDP Nachrichten und sende Echo zurck */
void process_incoming_udp()
{
if (udpServer.parsePacket())
{
// Nachricht abholen
int len=udpServer.read(udp_buffer,sizeof(udp_buffer)-1);
udp_buffer[len] = 0;
// Nachricht anzeigen
// Serial.print("Empfangen von ");
// Serial.print(udpServer.remoteIP());
// Serial.print(":");
// Serial.print(udpServer.remotePort());
// Serial.print(": ");
// Serial.println(udp_buffer);
// Nachricht als Echo zurck senden
// udpServer.beginPacket(udpServer.remoteIP(), udpServer.remotePort());
// udpServer.print("Echo: ");
// udpServer.print(udp_buffer);
// udpServer.endPacket();
// UDP Buffer auswerten
//-- Status Schalter ---------------------------------------------------------
//-- bt0 All LIGHTS ----------------------------------------------------------
if (strstr(udp_buffer, "s0=1")) {
sw_status0 |= 0x97;
sw_status1 |= 0x01;
sw_status0 &= ~0x20; //STROBE
MCP_GP1 |= REL_INTERCOM;
}
else if(strstr(udp_buffer, "s0=0")) {
sw_status0 &= ~0x97;
sw_status1 &= ~0x01;
MCP_GP1 &= ~REL_INTERCOM;
}
//-- bt1 SPOTS --------------------------------------------------------------
if (strstr(udp_buffer, "s1=1")) {
sw_status0 |= 0x02;
}
else if(strstr(udp_buffer, "s1=0")) {
sw_status0 &= ~0x02;
}
//-- bt2 FLOOR --------------------------------------------------------------
if (strstr(udp_buffer, "s2=1")) {
sw_status0 |= 0x04;
}
else if(strstr(udp_buffer, "s2=0")) {
sw_status0 &= ~0x04;
}
/*
//-- bt3 STARS LOCK-----------------------------------------------------------
if (strstr(udp_buffer, "s3=1")) {
sw_status0 |= 0x08;
}
else if(strstr(udp_buffer, "s3=0")) {
sw_status0 &= ~0x08;
}
*/
//-- bt4 STARS ---------------------------------------------------------------
if (strstr(udp_buffer, "s4=1")) {
sw_status0 |= 0x10;
}
else if(strstr(udp_buffer, "s4=0")) {
sw_status0 &= ~0x10;
}
//-- bt5 STROBE ---------------------------------------------------------------
if (strstr(udp_buffer, "s5=1")) {
sw_status0 |= 0x20;
}
else if(strstr(udp_buffer, "s5=0")) {
sw_status0 &= ~0x20;
}
//-- bt6 LASER --------------------------------------------------------------
if (strstr(udp_buffer, "s6=1")) {
sw_status0 |= 0x40;
}
else if(strstr(udp_buffer, "s6=0")) {
sw_status0 &= ~0x40;
}
//-- bt7 RIM LIGHTS ----------------------------------------------------------
if (strstr(udp_buffer, "s7=1")) {
sw_status0 |= 0x80;
}
else if(strstr(udp_buffer, "s7=0")) {
sw_status0 &= ~0x80;
}
//-- bt8 BACKLIGHT------------------------------------------------------------
if (strstr(udp_buffer, "s8=1")) {
sw_status1 |= 0x01;
}
else if(strstr(udp_buffer, "s8=0")) {
sw_status1 &= ~0x01;
}
//-- Status Tasten ------------------------------------------------------------
//-- b0 Trennwand hoch/zu -----------------------------------------------------
if (strstr(udp_buffer, "b0=1")) {
TMO_WALL = Timeout_wall_relay;
MCP_GP0 |= REL_WALL_UP;
MCP_GP0 &= ~REL_WALL_DWN;
transmit_cmd_ports();
}
else if(strstr(udp_buffer, "b0=0")) {
MCP_GP0 &= ~REL_WALL_UP;
MCP_GP0 &= ~REL_WALL_DWN;
transmit_cmd_ports();
}
//-- b1 Trennwand runter/auf --------------------------------------------------
else if (strstr(udp_buffer, "b1=1")) {
TMO_WALL = Timeout_wall_relay;
MCP_GP0 &= ~REL_WALL_UP;
MCP_GP0 |= REL_WALL_DWN;
transmit_cmd_ports();
}
else if(strstr(udp_buffer, "b1=0")) {
MCP_GP0 &= ~REL_WALL_UP;
MCP_GP0 &= ~REL_WALL_DWN;
transmit_cmd_ports();
}
//-- b7 MOOD -------------------------------------------------------------------
else if (strstr(udp_buffer, "b7=1")) {
if (TMO_BUTTONS == 0) {
select_mood_mode();
TMO_BUTTONS = Timeout_buttons_blocked;
}
}
//-- b9 SET LEFT ---------------------------------------------------------------
else if (strstr(udp_buffer, "b9=1")) {
if (TMO_BUTTONS == 0) {
PORTB |= CEILING_PLUS;
transmit_cmd_ports();
TMO_BUTTONS = Timeout_buttons_blocked;
}
}
//-- b10 SET RIGHT -------------------------------------------------------------
else if (strstr(udp_buffer, "ba=1")) {
if (TMO_BUTTONS == 0) {
PORTB |= CEILING_MINUS;
transmit_cmd_ports();
TMO_BUTTONS = Timeout_buttons_blocked;
}
}
//-- bt11 SET FLOOR ------------------------------------------------------------
else if (strstr(udp_buffer, "b2=1")) {
if (TMO_BUTTONS == 0) {
FB_protocol();
TMO_BUTTONS = Timeout_buttons_blocked;
}
}
//-- b11 STARS LOCK -----------------------------------------------------------
else if (strstr(udp_buffer, "bb=1")) {
MCP_GP0 |= STARS_LOCK;
TMO_STARS = Timeout_stars_relay;
#ifdef _debug
Serial.print("Stars Lock");
#endif
transmit_cmd_ports();
}
//-- b8 DIMMER UP --------------------------------------------------------------
else if (strstr(udp_buffer, "b8=1")) {
if (TMO_BUTTONS == 0) {
transmit_cmd_IR("61D6609F");
TMO_BUTTONS = Timeout_dimmer_blocked;
}
}
//-- b12 DIMMER DWN ------------------------------------------------------------
else if (strstr(udp_buffer, "bc=1")) {
if (TMO_BUTTONS == 0) {
transmit_cmd_IR("61D67887");
TMO_BUTTONS = Timeout_dimmer_blocked;
}
}
//-- Status Klima -------------------------------------------------------------
//-- j0 FAN -------------------------------------------------------------------
else if (strstr(udp_buffer, "j0=0")) {
fan_status = 0;
}
else if(strstr(udp_buffer, "j0=1")) {
fan_status = 1;
}
else if(strstr(udp_buffer, "j0=2")) {
fan_status = 2;
}
else if(strstr(udp_buffer, "j0=3")) {
fan_status = 3;
}
//-- n2 SOLL Temperatur ------------------------------------------------------
else if (strstr(udp_buffer, "n2="))
{
test = strstr(udp_buffer, "n2=");
soll_temperatur = *(test + 3) - 0x30;
}
}
}
/** Optional: Zeige an, wenn die Verbindung zum AP gendert wurde. */
void check_ap_connection()
{
static wl_status_t preStatus = WL_DISCONNECTED;
wl_status_t newStatus = WiFi.status();
if (newStatus != preStatus)
{
if (newStatus == WL_CONNECTED)
{
digitalWrite(LEDRT, HIGH);
#ifdef _debug
// Die eigene IP-Adresse anzeigen
Serial.print("AP Verbindung aufgebaut, lausche auf ");
Serial.print(WiFi.localIP());
Serial.print(":");
Serial.println(PORT);
#endif
}
else
{
digitalWrite(LEDRT, LOW);
#ifdef _debug
Serial.println("AP Verbindung verloren");
#endif
}
preStatus = newStatus;
}
}
void read_temperature() {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
if ( !ds.search(addr))
{
ds.reset_search();
delay(250);
return;
}
if (OneWire::crc8(addr, 7) != addr[7])
{
return;
}
// the first ROM byte indicates which chip
switch (addr[0])
{
case 0x10:
type_s = 1;
break;
case 0x28:
type_s = 0;
break;
case 0x22:
type_s = 0;
break;
default:
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
//delay(1000);
delay(100);
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++)
{
data[i] = ds.read();
}
// Convert the data to actual temperature
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10)
{
raw = (raw & 0xFFF0) + 12 - data[6];
}
}
else
{
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
}
celsius = (float)raw / 16.0;
}
// UDP Status Temperaturen und Geblse senden
void udp_message_status1() {
udpServer.beginPacket(IP_BROADCAST, PORT);
udpServer.print("ST=");
udpServer.print(soll_temperatur);
udpServer.print(" IT=");
udpServer.print((int) celsius);
udpServer.print(" FN=");
udpServer.print(fan_status);
/*
udpServer.print(" SW=");
String s1 = String(sw_status0, HEX);
if (s1.length() < 2) s1 = "0" + s1;
s1 = String(sw_status1, HEX) + s1;
if (s1.length() < 4) s1 = "0" + s1;
udpServer.print(s1);
*/
udpServer.println(" ");
udpServer.endPacket();
}
// UDP Status Schalter senden
void udp_message_status2() {
udpServer.beginPacket(IP_BROADCAST, PORT);
udpServer.print("SW=");
String s1 = String(sw_status0, HEX);
if (s1.length() < 2) s1 = "0" + s1;
s1 = String(sw_status1, HEX) + s1;
if (s1.length() < 4) s1 = "0" + s1;
udpServer.print(s1);
udpServer.println(" ");
udpServer.endPacket();
}
// Funktionen Schalter
void switches() {
// RIM Lights
if (sw_status0 & 0x80) {
PORTD |= REL_III_ON_OFF;
} else {
PORTD &= ~REL_III_ON_OFF;
}
// Backlight
if (sw_status1 & 0x01) {
PORTB |= REL_VI_ON_OFF;
} else {
PORTB &= ~REL_VI_ON_OFF;
}
// SPOTS
if (sw_status0 & 0x02) {
MCP_GP0 |= IN_DOOR_SW;
} else {
MCP_GP0 &= ~IN_DOOR_SW;
}
// STROBE
if (sw_status0 & 0x20) {
PORTD &= ~REL_IV_ON_OFF;
MCP_GP1 |= REL_INTERCOM;
} else {
PORTD |= REL_IV_ON_OFF;
// MCP_GP1 &= ~REL_INTERCOM;
}
// STARS
if (sw_status0 & 0x10) {
PORTD |= REL_II_ON_OFF;
} else {
PORTD &= ~REL_II_ON_OFF;
}
// LASER
if (sw_status0 & 0x40) {
PORTD |= REL_I_ON_OFF;
} else {
PORTD &= ~REL_I_ON_OFF;
}
//FLOOR
if (sw_status0 & 0x04) {
PORTD |= REL_V_ON_OFF;
} else {
PORTD &= ~REL_V_ON_OFF;
}
}
// Klima und Heizungssteuerung - Zweipunktregler
void clima_control() {
// luefter
if (fan_status == 1) {
// Stufe 1
MCP_GP1 |= REL_FAN_I;
MCP_GP1 &= ~REL_FAN_II;
MCP_GP1 &= ~REL_FAN_III;
} else if (fan_status == 2) {
// Stufe 1
MCP_GP1 |= REL_FAN_I;
MCP_GP1 |= REL_FAN_II;
MCP_GP1 &= ~REL_FAN_III;
} else if (fan_status == 3) {
// Stufe 3
MCP_GP1 |= REL_FAN_I;
MCP_GP1 |= REL_FAN_II;
MCP_GP1 |= REL_FAN_III;
} else {
// AUS
MCP_GP1 &= ~REL_FAN_I;
MCP_GP1 &= ~REL_FAN_II;
MCP_GP1 &= ~REL_FAN_III;
}
// Kuehlen oder Heizen?
if (celsius < soll_temperatur) {
// Heizen
MCP_GP1 |= REL_HEATING;
MCP_GP1 &= ~REL_CLIMA;
} else if ((celsius > (soll_temperatur + 1)) && (celsius > 15)) {
// Kuehlen
MCP_GP1 &= ~REL_HEATING;
MCP_GP1 |= REL_CLIMA;
} else {
// Temperatur stimmt!
MCP_GP1 &= ~REL_HEATING;
MCP_GP1 &= ~REL_CLIMA;
}
}
// MOOD modi whlen
void select_mood_mode() {
switch(mood_mode)
{
case 0: // white
sw_status0 = 0x02; // Spots an, Strobo aus, Decke an
sw_status1 = 0;
switches();
MCP_GP1 |= REL_INTERCOM;
transmit_cmd_ports();
delay(200);
transmit_cmd_IR("61D68877"); // W
break;
case 1: // Disco
sw_status0 = 0xF4; // Laser, Stars, Rim Light und Floor, Strobo an
sw_status1 = 0;
switches();
MCP_GP1 |= REL_INTERCOM;
transmit_cmd_ports();
delay(200);
transmit_cmd_IR("61D600FF"); // P8
break;
case 2: // Nacht
sw_status0 = 0x10; // Stars,
sw_status1 = 0x00;
switches();
MCP_GP1 |= REL_INTERCOM; // Trennwandbeleuchtung & Deckenbalken an.
transmit_cmd_ports();
delay(200);
transmit_cmd_IR("61D648B7"); // M3
break;
}
mood_mode++;
if (mood_mode > 2) mood_mode = 0;
}
//FB Protokoll auswhlen
void FB_protocol() {
switch(FB_mode)
{
case 0: // Button W1
transmit_cmd_IR("61D68877");
break;
case 1: // Button m1
transmit_cmd_IR("61D6C837");
break;
case 2: // Button m2
transmit_cmd_IR("61D608F7");
break;
case 3: // Button m3
transmit_cmd_IR("61D648B7");
break;
case 4: // Button m4
transmit_cmd_IR("61D658A7");
break;
case 5: // Button m5
transmit_cmd_IR("61D6C03F");
break;
case 6: // Button m6
transmit_cmd_IR("61D640BF");
break;
case 7: // Button P1
transmit_cmd_IR("61D610EF");
break;
case 8: // Button P2
transmit_cmd_IR("61D6906F");
break;
case 9: // Button P3
transmit_cmd_IR("61D6D827");
break;
case 10: // Button P4
transmit_cmd_IR("61D6F807");
break;
case 11: // Button P5
transmit_cmd_IR("61D630CF");
break;
case 12: // Button P6
transmit_cmd_IR("61D618E7");
break;
case 13: // Button P7
transmit_cmd_IR("61D628D7");
break;
case 14: // Button P8
transmit_cmd_IR("61D600FF");
break;
}
FB_mode++;
if (FB_mode > 14) FB_mode = 0;
}
// -- Hilfsroutinen fr Portexpander und Mikrocontroller -------------------------------------------------------------------------
// bertragung der Statusdaten fr alle IOs an den Mikrocontroller
void transmit_cmd_ports() {
String S1 = "IO=";
//convert PortB
String S2 = String(PORTB, HEX);
if (PORTB < 16) S2 = "0" + S2;
S1 = S1 + S2;
// convert PortC
S2 = String(PORTC, HEX);
if (PORTC < 16) S2 = "0" + S2;
S1 = S1 + S2;
// convert PortD
S2 = String(PORTD, HEX);
if (PORTD < 16) S2 = "0" + S2;
S1 = S1 + S2;
// convert MCP_GP0
S2 = String(MCP_GP0, HEX);
if (MCP_GP0 < 16) S2 = "0" + S2;
S1 = S1 + S2;
// convert MCP_GP1
S2 = String(MCP_GP1, HEX);
if (MCP_GP1 < 16) S2 = "0" + S2;
S1 = S1 + S2;
#ifdef _debug
Serial.println(S1);
#endif
ESPserial.println(S1);
}
// bertragung eines IR-Befehls an den Mikrocontroller
void transmit_cmd_IR(String S1) {
if (S1.length() != 8) return;
S1 = "IR=" + S1;
#ifdef _debug
Serial.println(S1);
#endif
ESPserial.println(S1);
}
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <SoftwareSerial.h>
// enable debug outputs via serial Port 1 (USB)
//#define _debug_snd
//#define _debug_rec
// Portkonfiguration
#define LEDBL 2 //interne blaue LED an GPIO2 des Wemos
#define LEDRT 14 //rote LED an GPIO5 (D1) des Wemos
SoftwareSerial ESPserial(12, 13); // RX (D6) | TX (D7)
// Name und Passwort des Access Points
#define SSID "xxxxx"
#define PASSWORD "xxxxx"
// Der Server nimmt Verbindungen auf diesem Port an
#define PORT 5444
#define IP_BROADCAST "192.168.0.255"
WiFiUDP udpServer;
#define WIFICLIENT_MAX_PACKET_SIZE 200
// Puffer fr hereinkommende UDP Nachrichten
char udp_buffer[WIFICLIENT_MAX_PACKET_SIZE+1];
// Variables
int i1;
char *test;
String s1;
String inputString;
int TMR_UDP_REC_BLOCK=0;
/** Wird beim Start einmal ausgefhrt */
void setup()
{
// LED blau aus
pinMode(LEDBL, OUTPUT);
digitalWrite(LEDBL, HIGH);
// LED rot aus
pinMode(LEDRT, OUTPUT);
digitalWrite(LEDRT, LOW);
// Seriellen Port 2 initialisieren
ESPserial.begin(9600); // Start the software serial for communication with the ESP8266
// Gib dem seriellen Port Monitor von der Arduino
// IDE ein bisschen Zeit.
#ifdef _debug_snd
Serial.begin(115200); // Seriellen Port1 (USB) fr Debugging initialisieren.
#endif
delay(250);
// Benutze einen externen AP
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASSWORD);
// UDP Server starten
udpServer.begin(PORT);
}
/** Hauptschleife, wird wiederholt ausgefhrt. */
void loop()
{
process_incoming_udp();
check_ap_connection();
while (ESPserial.available()) {
// get the new byte:
char inChar = (char)ESPserial.read();
#ifdef _debug
Serial.print(inChar);
#endif
// yield();
// add it to the inputString:
inputString += inChar;
//if (inChar == 0xFF) Nextion_auswerten();
if (inChar == '|') Nextion_auswerten();
}
if (TMR_UDP_REC_BLOCK) TMR_UDP_REC_BLOCK--;
delay(1);
}
/** Empfange UDP Nachrichten und sende Echo zurck */
void process_incoming_udp()
{
if (udpServer.parsePacket())
{
// Nachricht abholen
int len=udpServer.read(udp_buffer,sizeof(udp_buffer)-1);
udp_buffer[len] = 0;
// Nachricht anzeigen
// Serial.print("Empfangen von ");
// Serial.print(udpServer.remoteIP());
// Serial.print(":");
// Serial.print(udpServer.remotePort());
// Serial.print(": ");
// Serial.println(udp_buffer);
// Nachricht als Echo zurck senden
// udpServer.beginPacket(udpServer.remoteIP(), udpServer.remotePort());
// udpServer.print("Echo: ");
// udpServer.print(udp_buffer);
// udpServer.endPacket();
// Nextion Befehle senden, wenn vorhanden
// udpServer.beginPacket(udpServer.remoteIP(), udpServer.remotePort());
// if (UDP_TMT_String.length > 0) {
// udpServer.println("TEST 123");
//}
// udpServer.endPacket();
// Auf bestimmte Befehle reagieren
// Ist-Temperatur setzen
if (strstr(udp_buffer, "IT="))
{
test = strstr(udp_buffer, "IT=");
if (*(test + 3) == '-') {
s1 = "-" + String(*(test + 4)) + String(*(test + 5));
} else {
s1 = String(*(test + 3)) + String(*(test + 4));
}
#ifdef _debug_rec
Serial.print("Wert IT: ");
Serial.println(s1.toInt());
#endif
digitalWrite(LEDRT, HIGH);
// udpServer.println("LED ist an");
ESPserial.print("n0.val=");
ESPserial.print(s1.toInt());
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
}
if (TMR_UDP_REC_BLOCK) return;
// Soll-Temperatur setzen
if (strstr(udp_buffer, "ST="))
{
test = strstr(udp_buffer, "ST=");
s1 = String(*(test + 3)) + String(*(test + 4));
#ifdef _debug_rec
Serial.print("Wert ST: ");
Serial.println(s1.toInt());
#endif
//digitalWrite(LEDRT, LOW);
ESPserial.print("n2.val=");
ESPserial.print(s1.toInt());
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
}
// Luefter setzen
if (strstr(udp_buffer, "FN="))
{
test = strstr(udp_buffer, "FN=");
if (*(test + 3) == '1') {
i1=33;
} else if (*(test + 3) == '2') {
i1=66;
} else if (*(test + 3) == '3') {
i1=100;
} else {
i1=0;
}
#ifdef _debug_rec
Serial.print("Wert FN: ");
Serial.println(i1);
#endif
ESPserial.print("j0.val=");
ESPserial.print(i1);
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
}
// alle switches synchronisieren
if (strstr(udp_buffer, "SW="))
{
test = strstr(udp_buffer, "SW=");
byte b0= StrToHex(String(*(test + 5)) + String(*(test + 6)),3);
byte b1= StrToHex(String(*(test + 3)) + String(*(test + 4)),3);
#ifdef _debug_rec
Serial.print("Wert SW Byte0: ");
Serial.println(b0);
Serial.print("Wert SW Byte1: ");
Serial.println(b1);
#endif
// Status bt0
ESPserial.print("bt0.val=");
if (b0 & 0x01) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
// Status bt1
ESPserial.print("bt1.val=");
if (b0 & 0x02) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
// Status bt2
ESPserial.print("bt2.val=");
if (b0 & 0x04) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
/*
// Status bt3
ESPserial.print("bt3.val=");
if (b0 & 0x08) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
*/
// Status bt4
ESPserial.print("bt4.val=");
if (b0 & 0x10) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
// Status bt5
ESPserial.print("bt5.val=");
if (b0 & 0x20) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
// Status bt6
ESPserial.print("bt6.val=");
if (b0 & 0x40) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
// Status bt7
ESPserial.print("bt7.val=");
if (b0 & 0x80) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
// Status bt8
ESPserial.print("bt8.val=");
if (b1 & 0x01) {
ESPserial.print(1);
} else {
ESPserial.print(0);
}
ESPserial.write(0xff);
ESPserial.write(0xff);
ESPserial.write(0xff);
}
}
}
/** Optional: Zeige an, wenn die Verbindung zum AP gendert wurde. */
void check_ap_connection()
{
static wl_status_t preStatus = WL_DISCONNECTED;
wl_status_t newStatus = WiFi.status();
if (newStatus != preStatus)
{
if (newStatus == WL_CONNECTED)
{
digitalWrite(LEDRT, HIGH);
#ifdef _debug_rec
// Die eigene IP-Adresse anzeigen
Serial.print("AP Verbindung aufgebaut, lausche auf ");
Serial.print(WiFi.localIP());
Serial.print(":");
Serial.println(PORT);
#endif
}
else
{
digitalWrite(LEDRT, LOW);
#ifdef _debug_rec
Serial.println("AP Verbindung verloren");
#endif
}
preStatus = newStatus;
}
}
unsigned long StrToHex(String str, byte digits)
{
char ConvByte[10];
str.toCharArray(ConvByte, digits);
return (unsigned long) strtol(ConvByte, NULL, 16);
}
void Nextion_auswerten()
{
int i2=inputString.indexOf("=");
if (i2 > 0) {
#ifdef _debug_snd
Serial.print("Nextion: ");
Serial.print(inputString);
Serial.println(" - ");
Serial.print(inputString.substring(i2-2,i2));
Serial.print("=");
Serial.println(inputString[i2+1]);
#endif
udpServer.beginPacket(IP_BROADCAST, PORT);
udpServer.print(inputString.substring(i2-2,i2));
udpServer.print("=");
udpServer.print(inputString[i2+1]);
udpServer.println(" ");
udpServer.endPacket();
TMR_UDP_REC_BLOCK = 2000;
//delay(20);
}
while(Serial.available()) {Serial.read();}
inputString = "";
}
Comments
Please log in or sign up to comment.