IR Receive, Send + Webservice Call
› Forums › (Deutsch) User Projekte › IR Receive, Send + Webservice Call
- This topic has 2 replies, 2 voices, and was last updated 7 years, 11 months ago by Puuh.
-
AuthorPosts
-
January 15, 2016 at 03:52 #1103TerraParticipant
Hallo Leute,
Ich versuche jetzt seit ein paar Tagen meinem NanoESP folgendes beizubringen:
WENN:
– Ich 3x die “TV” Taste meiner Fernbedienung drückeDANN:
– Soll sich mein Beamer ausschalten (durch 3x dasselbe IR Signal senden)
– Mein Yamaha AV-Receiver ausschalten (durch Webservice Call auf lokale IP)Das ganze funktioniert getrennt schon sehr gut, ich habe ein Script das bei dreimal drücken der taste “TV” auf meiner Fernbedienung 3x das Signal zum Beamer ausschalten sendet und einmal ein weiteres Script das beim starten den WebService Call an den Yamaha AV Receiver schickt. Beides funktioniert unabhängig tadellos.
Jetzt habe ich die beiden Scripts in ein Script gepackt und der WebService Call geht leider nicht, ich bekomme immer eine Fehlermeldung des NanoESP das der Call nicht geschickt werden kann.
Ich vermute das der Speicher zu klein wird obwohl die GUI nichts anzeigt :/Ich hab schon überall probiert Speicher zu sparen, aber ich denke das Problem liegt an dem langen String den ich über den WebService schicken muss. Kann ich den irgendwie Speicherschonender zusammenbauen und übergeben?
Relevanter Teil:
#define AVRStopMessage "<?xml version=\"1.0\" encoding=\"utf-8\"?><YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>Standby</Power></Power_Control></Main_Zone></YAMAHA_AV>" String getRequest = "POST "+Subpage+" HTTP/1.1\r\nHost:"+Host+"\r\nContent-Type: text/xml;charset=\"UTF-8\"\r\nAccept: text/xml\r\nContent-Length: " + String(strlen(AVRStopMessage)+1) + "\r\n\r\n" + String(AVRStopMessage) + "\r\n"; sendCom("AT+CIPSTART=\"TCP\",\""+Host+"\",80", "OK"); sendCom("AT+CIPSEND=" + String(getRequest.length() + 2), ">"); esp8266.println(getRequest);
Das ganze Script:
#include <IRremote.h> #include <SoftwareSerial.h> SoftwareSerial esp8266(11, 12); // RX, TX #define SSID "*****" #define PASSWORD "*****" #define AVRHost "192.168.0.12" #define AVRSubpage "/YamahaRemoteControl/ctrl" /* Yamaha XML Messages Note! - AVROutputSetVolume has -39 hardcoded as defined volume - AVROutputHDMI1 the outputs of the Yamaha must be set via the NAMES that were assigned in the configuration. My HDMI1 output is called HTPC. Default it most likely the name is HDMI1. "HTPC" is hardcoded in the request! All of the extra ones are disabled because of space issues... */ #define AVRStopMessage "<?xml version=\"1.0\" encoding=\"utf-8\"?><YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>Standby</Power></Power_Control></Main_Zone></YAMAHA_AV>" /* Some IR Codes TURN BEAMER ON Value: 4CB340BF Type: 3 Length: 32 TURN BEAMER OFF Value: 4CB3748B Type: 3 Length: 32 TURN RECEIVER ON/OFF Value: 7E8154AB Type: 3 Length: 32 - And add a FFFFFFFF Type 3 Length 0 Type 2 up type 2 800F041E down type2 800F841F */ unsigned long timenow = 1; unsigned long receivedBeamerOnSignal1 = 0; unsigned long receivedBeamerOnSignal2 = 0; unsigned long receivedBeamerOnSignal3 = 0; unsigned long repeatTimeoutMillisThreshold = 1000; #define LED_WLAN 13 #define GND 4 #define RECV_PIN 7 #define GND2 8 #define VCC 9 IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; // Storage for the recorded code int codeType = -1; // The type of code unsigned long codeValue; // The code value if not raw unsigned int rawCodes[RAWBUF]; // The durations if raw int codeLen; // The length of the code void setup() { Serial.begin(19200); irrecv.enableIRIn(); // Start the receiver esp8266.begin(19200); //Set Pins for LED and IR Monitor pinMode(GND, OUTPUT); pinMode(GND2, OUTPUT); pinMode(VCC, OUTPUT); digitalWrite (GND, LOW); digitalWrite (GND2, LOW); digitalWrite (VCC, HIGH); if (!espConfig()) serialDebug(); else digitalWrite(LED_WLAN, HIGH); } void loop() { //Serial.println("I am Alive!"); timenow = millis(); //IR RECEIVER SIGNAL if (irrecv.decode(&results)) { analyzeCode(&results); Serial.println("Received IR!"); irrecv.resume(); } } // Stores the code for later playback // Most of this code is just logging void analyzeCode(decode_results *results) { codeType = results->decode_type; int count = results->rawlen; String receivedSignal; if (codeType == UNKNOWN) { //Serial.println("Received unknown code, saving as raw"); codeLen = results->rawlen - 1; // To store raw codes: // Drop first value (gap) // Convert from ticks to microseconds // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion for (int i = 1; i <= codeLen; i++) { if (i % 2) { // Mark rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS; //Serial.print(" m"); } else { // Space rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS; //Serial.print(" s"); } //Serial.print(rawCodes[i - 1], DEC); } //Serial.println(""); } else { if (codeType == NEC) { //debug("Received NEC: "); if (results->value == REPEAT) { // Don't record a NEC repeat value as that's useless. //debug("repeat; ignoring."); return; } } receivedSignal = String(results->value, HEX); receivedSignal.toUpperCase(); // So now we are listening if someone has send the BEAMER ON ir signal 3 times in a row. // we have three variables to store the millisecond when the signal was received. // the next variable iteration will be populated by the system if the last signal was send less than // repeatTimeoutMillis milliseconds. // e.g. if repeatTimeoutMillis=500 it means a signal is valid repeated when the previous signal was // send not longer than half a second before! // Until it reaches the third iteration where it executes the command after 3 repeats of the signal. // In case the previous signal was send longer than repeatTimeoutMillis ago the iteration resets and // sets the newly received signal as iteration 1 to start the cyrcle with this signal again. // if(receivedSignal == "4CB340BF") { debug("--------Detected My Signal!"); if(receivedBeamerOnSignal1 == 0) { receivedBeamerOnSignal1 = timenow; debug("----SET RS1"); } else if(receivedBeamerOnSignal1 != 0 && receivedBeamerOnSignal2 == 0) { receivedBeamerOnSignal2 = timenow; if( receivedBeamerOnSignal2 > receivedBeamerOnSignal1+repeatTimeoutMillisThreshold ) { receivedBeamerOnSignal1 = timenow; receivedBeamerOnSignal2 = 0; receivedBeamerOnSignal3 = 0; debug("----RESET ON RS2: "); } else { debug("----SET RS2"); } } else if(receivedBeamerOnSignal2 != 0) { receivedBeamerOnSignal3 = timenow; if( receivedBeamerOnSignal3 > receivedBeamerOnSignal2+repeatTimeoutMillisThreshold ) { receivedBeamerOnSignal1 = timenow; receivedBeamerOnSignal2 = 0; receivedBeamerOnSignal3 = 0; debug("----RESET ON RS3: "); } else { debug("----SET RS3"); //esp8266.end(); delay(200); //TURN OFF BEAMER BEGIN debug("--------TURN OFF BEAMER !!!"); irsend.sendNEC(0x4CB3748B, 32); delay(200); irsend.sendNEC(0x4CB3748B, 32); delay(200); irsend.sendNEC(0x4CB3748B, 32); //TURN OFF BEAMER END //TURN OFF RECEIVER BEGIN manageAVR(AVRHost, AVRSubpage); //TURN OFF RECEIVER END //reenable IR receiver after sending irrecv.enableIRIn(); irrecv.resume(); receivedBeamerOnSignal1 = 0; receivedBeamerOnSignal2 = 0; receivedBeamerOnSignal3 = 0; } } } codeValue = results->value; codeLen = results->bits; } } //--------------------------------------Yamaha AVR Functions-------------------------------------- void manageAVR(String Host, String Subpage) { String getRequest = "POST "+Subpage+" HTTP/1.1\r\nHost:"+Host+"\r\nContent-Type: text/xml;charset=\"UTF-8\"\r\nAccept: text/xml\r\nContent-Length: " + String(strlen(AVRStopMessage)+1) + "\r\n\r\n" + String(AVRStopMessage) + "\r\n"; sendCom("AT+CIPSTART=\"TCP\",\""+Host+"\",80", "OK"); sendCom("AT+CIPSEND=" + String(getRequest.length() + 2), ">"); esp8266.println(getRequest); //debug(getRequest); if (esp8266.find("+IPD")) { if (esp8266.find("\r\n\r\n")) { sendCom("AT+CIPCLOSE", "OK"); } } } //-----------------------------------------Config ESP8266------------------------------------ boolean espConfig() { boolean succes = true; esp8266.setTimeout(5000); succes &= sendCom("AT+RST", "ready"); esp8266.setTimeout(1000); if (configStation(SSID, PASSWORD)) { succes &= true; debug("WLAN OK"); debug("IP:"); debug(sendCom("AT+CIFSR")); } else { succes &= false; } //shorter Timeout for faster wrong UPD-Comands handling succes &= sendCom("AT+CIPMODE=0", "OK"); succes &= sendCom("AT+CIPMUX=0", "OK"); return succes; } boolean configStation(String vSSID, String vPASSWORT) { boolean succes = true; succes &= (sendCom("AT+CWMODE=1", "OK")); esp8266.setTimeout(20000); succes &= (sendCom("AT+CWJAP=\"" + String(vSSID) + "\",\"" + String(vPASSWORT) + "\"", "OK")); esp8266.setTimeout(1000); return succes; } //-----------------------------------------------Controll ESP----------------------------------------------------- boolean sendCom(String command, char respond[]) { esp8266.println(command); if (esp8266.findUntil(respond, "ERROR")) { return true; } else { debug("ESP ERR: " + command); return false; } } String sendCom(String command) { esp8266.println(command); return esp8266.readString(); } //-------------------------------------------------Debug Functions------------------------------------------------------ void serialDebug() { while (true) { if (esp8266.available()) Serial.write(esp8266.read()); if (Serial.available()) esp8266.write(Serial.read()); } } void debug(String Msg) { Serial.println("FR:" + String(freeRam()) + " - " + Msg); } int freeRam() { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }
lg und danke
January 15, 2016 at 22:41 #1107TerraParticipantIch hab den Fehler inzwischen gefunden, es war wie vermutet die Variable/Konstante:
#define AVRStopMessage “<?xml version=\”1.0\” encoding=\”utf-8\”?><YAMAHA_AV cmd=\”PUT\”><Main_Zone><Power_Control><Power>Standby</Power></Power_Control></Main_Zone></YAMAHA_AV>”
Wenn ich die Zeichenkette im obigen Programm reduziere schickt er den Webservice Call, ansonsten nicht.
Ich hab jetzt nochmal ein paar debug ausgaben verkürzt, HTTP Header entfernt und ein paar Sachen anders gelöst oder gelöscht, jetzt klappt alles :)WENN:
– Ich 3x die “TV” Taste meiner Fernbedienung drückeDANN:
– Soll sich mein Beamer ausschalten (durch 3x dasselbe IR Signal senden)
– Mein Yamaha AV-Receiver ausschalten (durch Webservice Call auf lokale IP)
– Zusätzlich blinkt eine LED bei jedem IR Signal das er empfängt, nur damit ich sehe ob er noch zuhört.#include <IRremote.h> #include <SoftwareSerial.h> SoftwareSerial esp8266(11, 12); // RX, TX const char* WiFiSSID = "*****"; const char* WiFiPASSWORD = "*****"; const char* AVRHost = "192.168.0.12"; const char* AVRSubpage = "/YamahaRemoteControl/ctrl"; /* Yamaha XML Messages Note! - AVROutputSetVolume has -39 hardcoded as defined volume - AVROutputHDMI1 the outputs of the Yamaha must be set via the NAMES that were assigned in the configuration. My HDMI1 output is called HTPC. Default it most likely the name is HDMI1. "HTPC" is hardcoded in the request! All of the extra ones are disabled because of space issues... */ const char* AVRStopMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?><YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>Standby</Power></Power_Control></Main_Zone></YAMAHA_AV>"; /* Some IR Codes TURN BEAMER ON Value: 4CB340BF Type: 3 Length: 32 TURN BEAMER OFF Value: 4CB3748B Type: 3 Length: 32 TURN RECEIVER ON/OFF Value: 7E8154AB Type: 3 Length: 32 - And add a FFFFFFFF Type 3 Length 0 Type 2 up type 2 800F041E down type2 800F841F */ const char* sigBeamerOn = "4CB340BF"; //const char* sigBeamerOff = "4CB3748B"; //const char* sigAVReceiverOnOff = "7E8154AB"; unsigned long timenow = 1; unsigned long receivedBeamerOnSignal1 = 0; unsigned long receivedBeamerOnSignal2 = 0; unsigned long receivedBeamerOnSignal3 = 0; const long repeatTimeoutMillisThreshold = 1000; const int LED_WLAN = 13; const int GND = 2; const int RECV_PIN = 7; const int GND2 = 8; const int VCC = 9; const int LED = 5; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; void setup() { Serial.begin(19200); irrecv.enableIRIn(); // Start the receiver esp8266.begin(19200); //Set Pins for LED and IR Monitor pinMode(GND, OUTPUT); pinMode(GND2, OUTPUT); pinMode(VCC, OUTPUT); pinMode(LED, OUTPUT); digitalWrite (GND, LOW); digitalWrite (GND2, LOW); digitalWrite (VCC, HIGH); if (!espConfig()) serialDebug(); else digitalWrite(LED_WLAN, HIGH); } void loop() { //Serial.println("I am Alive!"); //IR RECEIVER SIGNAL if (irrecv.decode(&results)) { timenow = millis(); analyzeCode(&results); Serial.print(F("ir")); digitalWrite(LED, 1); delay(50); digitalWrite(LED, 0); irrecv.resume(); } } void analyzeCode(decode_results *results) { results->decode_type; String receivedSignal; receivedSignal = String(results->value, HEX); receivedSignal.toUpperCase(); // So now we are listening if someone has send the PROJECTOR ON ir signal 3 times in a row. // we have three variables to store the millisecond when the signal was received. // the next variable iteration will be populated by the system if the last signal was send less than // repeatTimeoutMillis milliseconds. // e.g. if repeatTimeoutMillis=500 it means a signal is valid repeated when the previous signal was // send not longer than half a second before! // Until it reaches the third iteration where it executes the command after 3 repeats of the signal. // In case the previous signal was send longer than repeatTimeoutMillis ago the iteration resets and // sets the newly received signal as iteration 1 to start the cycle with this signal again. // if(receivedSignal == sigBeamerOn) { Serial.println(F("+")); //Detected My Signal if(receivedBeamerOnSignal1 == 0) { receivedBeamerOnSignal1 = timenow; Serial.println(F("1")); //Set 1 } else if(receivedBeamerOnSignal1 != 0 && receivedBeamerOnSignal2 == 0) { receivedBeamerOnSignal2 = timenow; if( receivedBeamerOnSignal2 > receivedBeamerOnSignal1+repeatTimeoutMillisThreshold ) { receivedBeamerOnSignal1 = timenow; receivedBeamerOnSignal2 = 0; receivedBeamerOnSignal3 = 0; Serial.println(F("r2")); //Reset on 2 } else { Serial.println(F("2")); //Set 2 } } else if(receivedBeamerOnSignal2 != 0) { receivedBeamerOnSignal3 = timenow; if( receivedBeamerOnSignal3 > receivedBeamerOnSignal2+repeatTimeoutMillisThreshold ) { receivedBeamerOnSignal1 = timenow; receivedBeamerOnSignal2 = 0; receivedBeamerOnSignal3 = 0; Serial.println(F("r3")); //Reset on 3 } else { Serial.println(F("3")); //Set 3 delay(200); //TURN OFF PROJECTOR BEGIN Serial.println(F("xb")); //Turn off projector irsend.sendNEC(0x4CB3748B, 32); delay(200); irsend.sendNEC(0x4CB3748B, 32); delay(200); irsend.sendNEC(0x4CB3748B, 32); delay(200); irsend.sendNEC(0x4CB3748B, 32); //reenable IR receiver after sending irrecv.enableIRIn(); //TURN OFF PROJECTOR END Serial.println(F("xr")); //Turn off AVR-Receiver //TURN OFF RECEIVER BEGIN manageAVR(); //TURN OFF RECEIVER END receivedBeamerOnSignal1 = 0; receivedBeamerOnSignal2 = 0; receivedBeamerOnSignal3 = 0; } } } } //--------------------------------------Yamaha AVR Functions-------------------------------------- void manageAVR() { //Usually there are more headers in the original request, but we need to save space and cannot add them String getRequest = "POST "+String(AVRSubpage)+" HTTP/1.1\r\nHost:"+String(AVRHost)+"\r\nContent-Length: " + String(strlen(AVRStopMessage)+1) + "\r\n\r\n" + String(AVRStopMessage) + "\r\n"; sendCom("AT+CIPSTART=\"TCP\",\""+String(AVRHost)+"\",80", "OK"); sendCom("AT+CIPSEND=" + String(getRequest.length() + 2), ">"); esp8266.println(getRequest); Serial.println(getRequest); delay(1000); if (esp8266.find("+IPD")) { if (esp8266.find("\r\n\r\n")) { sendCom("AT+CIPCLOSE", "OK"); } } } //-----------------------------------------Config ESP8266------------------------------------ boolean espConfig() { boolean success = true; esp8266.setTimeout(5000); success &= sendCom("AT+RST", "ready"); esp8266.setTimeout(1000); if (configStation()) { success &= true; Serial.println(F("WLAN OK")); Serial.println(F("IP:")); Serial.println(sendCom("AT+CIFSR")); } else { success &= false; } //shorter Timeout for faster wrong UPD-Comands handling success &= sendCom("AT+CIPMODE=0", "OK"); success &= sendCom("AT+CIPMUX=0", "OK"); return success; } boolean configStation() { boolean success = true; success &= (sendCom("AT+CWMODE=1", "OK")); esp8266.setTimeout(20000); success &= (sendCom("AT+CWJAP=\"" + String(WiFiSSID) + "\",\"" + String(WiFiPASSWORD) + "\"", "OK")); esp8266.setTimeout(1000); return success; } //-----------------------------------------------Controll ESP----------------------------------------------------- boolean sendCom(String command, char respond[]) { esp8266.println(command); if (esp8266.findUntil(respond, "ERROR")) { return true; } else { Serial.println("ESP ERR: " + command); return false; } } String sendCom(String command) { esp8266.println(command); return esp8266.readString(); } //-------------------------------------------------Debug Functions------------------------------------------------------ void serialDebug() { }
- This reply was modified 8 years, 10 months ago by Terra.
- This reply was modified 8 years, 10 months ago by fk.
Attachments:
December 5, 2016 at 10:03 #1698PuuhParticipantHi, ich programmiere auch gerade ein IR Modul und möchte meinen Yamaha Receiver steuern. Der Code 0x7E8154AB ist ja für Power. Wie hast du diesen Code ermittelt bzw. wo hast du diesen Code gefunden? Ich suche bislang vergeblich nach den Codes der gesamten RV300 Fernbedienung.
Viele Grüße
Puuh -
AuthorPosts
- You must be logged in to reply to this topic.