#define DEBUG 1 #define ANIM_FILE_NAME "/ANIMS.FRM" #define FILE_READ "r" #define FILE_WRITE "w" #define FBLENGTH 65 #define SERBFLENGTH 32 #define SERVER_PORT 80 #define MAX_SEND_RETRY 10 #define MAX_ANIMKEY_LENGTH 12 #define MY_CUBE_ADDR 2 //#include #include #include #include #include //#include #include #ifdef DEBUG #define DEBUG_PRINTLN(x) Serial.println (x) #define DEBUG_PRINT(x) Serial.print (x) #define DEBUG_PRINT2(x,y) Serial.print (x,y) #define DEBUG_PRINTLN_TXT(x) Serial.println (F(x)) #define DEBUG_PRINT_TXT(x) Serial.print (F(x)) #else #define DEBUG_PRINTLN(x) #define DEBUG_PRINT(x) #define DEBUG_PRINT2(x,y) #define DEBUG_PRINTLN_TXT(x) #define DEBUG_PRINT_TXT(x) #endif unsigned const char lc_slash = '/'; unsigned const char lc_question = '?'; unsigned const char lc_coma = ','; unsigned const char lc_space = ' '; unsigned const char lc_f = 'f'; unsigned const char lc_F = 'F'; unsigned const char lc_s = 's'; unsigned const char lc_S = 'S'; unsigned char myAnimationCount = 0; unsigned int _animationSpeed = 0; unsigned long _animationLength = 0; unsigned long _animationStartPos = 0; unsigned long _animationEndPos = 0; unsigned int _animationActFrame = 0; unsigned long _previousMillis = 0; // will store last time animation frame was sent unsigned char ga_buffer1[FBLENGTH]; unsigned char gi_buffer1_pos = 0; unsigned char ga_buffer2[FBLENGTH]; unsigned char gi_buffer2_pos = 0; unsigned char ga_sendBuffer[SERBFLENGTH]; unsigned char * gp_read_buffer; //unsigned char * gi_read_buffer_pos; unsigned char * gp_write_buffer; //unsigned char * gi_write_buffer_pos; int gi_status = 0; // 0 = unsigned long sendDelay = 1000; unsigned long lastChangeTime = 0; int gi_pos = 0; // Initialize the WiFi server library const char* ssid = "........"; const char* password = "........."; ESP8266WebServer server(SERVER_PORT); const char* www_username = "admin"; const char* www_password = "esp8266"; void fill_buffer_random(unsigned char * pp_buff) { for (int i=0; i MAX_SEND_RETRY ) { // everything went well or timeout try_again = false; success = true; }else{ // Something went wrong DEBUG_PRINTLN_TXT("Send failed"); } delayMicroseconds(10); } send_retries++; return success; } void sendBufferedFrame() { boolean lb_send_success; // Send start key ga_sendBuffer[0] = lc_slash; ga_sendBuffer[1] = lc_slash; ga_sendBuffer[2] = lc_question; ga_sendBuffer[3] = lc_question; lb_send_success = wireSendBytes(ga_sendBuffer, 4); if (lb_send_success == true ) { // First half frame wireSendBytes(gp_read_buffer, 32); for (unsigned char i=0;i<32;i++) { // Second half frame ga_sendBuffer[i] = gp_read_buffer[i+32]; } wireSendBytes(ga_sendBuffer, 32); } /* DEBUG_PRINTLN(""); for (int i=0;i(myKeyBuffer), myKeyLength) > -1) { // We found animation DEBUG_PRINTLN_TXT("Found animation"); myReadStatus = 20; // End search, we found our animation }else{ DEBUG_PRINTLN_TXT("No animation found"); if (_animationEndPos > _animationStartPos ) { // Goto next frame myProjectFile.seek(_animationEndPos, SeekSet); myReadStatus = 0; } } // clear buffer myIntBufferLength = 0; } break; case 6: if( myC == lc_newline ) { // uncomplete keyline or no animation found // check for values if ( _animationEndPos > 0 && _animationStartPos > 0 && _animationSpeed > 0 ) { DEBUG_PRINTLN_TXT("Anim key found"); }else{ DEBUG_PRINTLN_TXT("--keyline failed--"); // Reset everything myReadStatus = 0; myKeyLength = 0; myIntBufferLength = 0; clearSavedAnimation(); } } break; } } } myProjectFile.close(); } boolean readAnimationSD() { unsigned char myC; unsigned char myBytes = 0; // Read SD Card File myProjectFile = SPIFFS.open(ANIM_FILE_NAME, FILE_READ); // Goto start position if ( myProjectFile.available() ) { unsigned long _animationPos = _animationStartPos + _animationActFrame * 65; // startPos + offset if ( _animationPos < _animationEndPos ) { myProjectFile.seek(_animationPos, SeekSet); }else{ _animationActFrame = 0; // Start at the first frame again myProjectFile.seek(_animationStartPos, SeekSet); } } // Read one frame while ( myProjectFile.available() && myBytes < 64 ) { myC = myProjectFile.read(); myReceiveBuffer[myBytes] = myC; myBytes++; } // close the file: myProjectFile.close(); // If we have complete frame, return true if ( myBytes > 63 ) { // read successfull _animationActFrame++; return true; }else{ return false; } } unsigned long byte2Long(unsigned char* byteArray) { // little endian conversion unsigned long retval; retval = (unsigned long) byteArray[3] << 24 | (unsigned long) byteArray[2] << 16; retval |= (unsigned long) byteArray[1] << 8 | byteArray[0]; return retval; } void writeAnimationSDCard(WiFiClient client) { // Send answer unsigned char readBuffer[4]; // First 10 bytes is a key, following by the length readBuffer[0] = myReadBuffer[10]; readBuffer[1] = myReadBuffer[11]; readBuffer[2] = myReadBuffer[12]; readBuffer[3] = myReadBuffer[13]; unsigned long fileSize = byte2Long(readBuffer); // DEBUG_PRINT_TXT("fileSizeBuffer: "); for (unsigned char i=0; i<4; i++ ) { client.write(readBuffer[i]); // DEBUG_PRINT(readBuffer[i]); } client.write(lc_return); client.write(lc_newline); // DEBUG_PRINTLN_TXT(" "); // DEBUG_PRINT_TXT("Filesize expected:"); // DEBUG_PRINTLN(fileSize); // Blocking mode to write receiving data to file if (client) { // Remove file if exists if ( SPIFFS.exists(ANIM_FILE_NAME) ) { SPIFFS.remove(ANIM_FILE_NAME); } File myProjectFile = SPIFFS.open(ANIM_FILE_NAME, FILE_WRITE); unsigned long receivedBytes = 0; if (myProjectFile) { while (client.connected() && receivedBytes < fileSize) { if (client.available()) { unsigned char c = client.read(); //writing bytes myProjectFile.write(c); receivedBytes++; } } } /* if ( receivedBytes == fileSize ) { DEBUG_PRINTLN_TXT("Complete data received\n"); }else{ DEBUG_PRINTLN_TXT("Data incomplete\n"); } DEBUG_PRINT_TXT("Expected:"); DEBUG_PRINTLN(fileSize); DEBUG_PRINT_TXT("Received:"); DEBUG_PRINTLN(receivedBytes); */ myProjectFile.close(); } } void displaySavedAnimation() { if ( _animationLength > 0 ) { // Animation was set unsigned long currentMillis = millis(); // Display animation set over the network if ( currentMillis < _animationLength ) { // __animationLength = startTime + animLengthTime if ( _animationStartPos > 0 && _animationEndPos > 0 && _animationSpeed > 0){ // validity check if ( _animationEndPos > _animationStartPos ) { //DEBUG_PRINTLN_TXT("Setting mode to 2"); setServerMode(2); // Switch the server mode if ( currentMillis - _previousMillis >= _animationSpeed ) { // Sent data with the set speed // save the last time you sent frame _previousMillis = currentMillis; // Fill Buffer if ( true == readAnimationSD() ) { // Send buffered frame sendBufferedFrame(); } } } } }else{ // End the stream mode setServerMode(0); } } } //END:---------FILE handler ------------------// //START:-------HTTP handler ------------------// void handleRoot() { if(!server.authenticate(www_username, www_password)) { return server.requestAuthentication(); }else{ server.send(200, "text/plain", "Login OK"); } } //END:--------HTTP handler -------------------// //START:------------SETUP-----------------// void setup() { Wire.begin(); //for ESP8266-12E SDA=D2 and SLC=D1 Wire.setClockStretchLimit(1500); #ifdef DEBUG Serial.begin(57600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } #endif // always use this to "mount" the filesystem bool result = SPIFFS.begin(); DEBUG_PRINT_TXT("SPIFFS opened: "); DEBUG_PRINTLN(result); // Start the WiFi connection WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); if(WiFi.waitForConnectResult() != WL_CONNECTED) { DEBUG_PRINTLN_TXT("WiFi Connect Failed! Rebooting..."); delay(1000); ESP.restart(); } //ArduinoOTA.begin(); server.on("/", handleRoot); server.begin(); DEBUG_PRINT_TXT("Server started http://"); DEBUG_PRINTLN(WiFi.localIP()); // Init the buffer gp_read_buffer = ga_buffer1; gp_write_buffer = ga_buffer2; // Random number generator randomSeed(123); } //END:---------------SETUP--------------// //START:-------------MAIN---------------// void loop() { #ifdef DEBUG if ( Serial.available() > 0 ) { // get incoming byte: char inByte = Serial.read(); if ( inByte == '+' ) { if ( sendDelay < 10000 ) { sendDelay = sendDelay + 100; } } if ( inByte == '-' ) { if ( sendDelay >= 100 ) { sendDelay = sendDelay - 100; } } if ( inByte == '1' ) { gi_status = 1; } if ( inByte == '0' ) { gi_status = 0; } //DEBUG_PRINTLN(inByte); DEBUG_PRINT_TXT("Delay: "); DEBUG_PRINTLN(sendDelay); DEBUG_PRINT_TXT("Status: "); DEBUG_PRINTLN(gi_status); } #endif unsigned long currentMillis = millis(); if ( gi_status == 1 && currentMillis - lastChangeTime > sendDelay) { lastChangeTime = currentMillis; // Fill the buffer with random data //fill_buffer_random(gp_read_buffer); fill_buffer_run1(gp_read_buffer); // Send data sendBufferedFrame(); //print_buffer(gp_read_buffer); //DEBUG_PRINT_TXT("Data sent. Check digit: "); //DEBUG_PRINTLN(gp_read_buffer[FBLENGTH-1]); //delay(sendDelay); } // handle the Webserver requests //ArduinoOTA.handle(); server.handleClient(); } //END:--------------MAIN----------------------//