//スピードメーター #include #include #include #include #include #include #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); const char* ssid = "ap-game-884e38"; //ご自分のルーターのSSIDに書き換えてください const char* password = "password"; //ご自分のルーターのパスワードに書き換えてください boolean SSE_on = false;//Server-Sent Events設定が済んだかどうかのフラグ WiFiServer server(80); WiFiClient client; long LastTime = 0; volatile int value = 0; volatile uint8_t prev = 0; volatile int lastvalue = 0; volatile int sokudo = 0; int wifi_mode = 0; int pin_mode = 0; //*****************セットアップ********************** void setup() { Serial.begin(115200);//このシリアル通信はモニター用 delay(10); Serial.println(""); //wifi モード取得 pinMode(4, INPUT_PULLUP); pin_mode = digitalRead(4); if (pin_mode == LOW){ Serial.println("offline"); }else{ Serial.println("wifi"); wifi_mode = 1; } //スピード取得 pinMode(12, INPUT); pinMode(13, INPUT); attachInterrupt(12, updateEncoder, CHANGE); attachInterrupt(13, updateEncoder, CHANGE); digitalWrite(12, HIGH); digitalWrite(13, HIGH); //OLED Wire.begin(0,2); // (SDA,SCL):ESP8266(IO_0)-OLED(SDA),(IO_1)-OLED(SCL) display.begin(SSD1306_SWITCHCAPVCC, 0x78>>1); // OLED ADDRESS display.clearDisplay(); // Clear the buffer. if (wifi_mode == 1){ wifi_setup(); } } void wifi_setup() { // Connect to WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); // Start the server server.begin(); Serial.println("Server started"); // Print the IP address Serial.println(WiFi.localIP()); // displey localIP on OLED display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(30,10); display.println("WiFi.localIP"); display.setCursor(30,40); display.println(WiFi.localIP()); display.display(); delay(2000); } void updateEncoder() { uint8_t a = digitalRead(12); uint8_t b = digitalRead(13); uint8_t ab = (a << 1) | b; uint8_t encoded = (prev << 2) | ab; if(encoded == 0b1101 || encoded == 0b0100 || encoded == 0b0010 || encoded == 0b1011){ value ++; } else if(encoded == 0b1110 || encoded == 0b0111 || encoded == 0b0001 || encoded == 0b1000) { value --; } prev = ab; Serial.print ("dist "); Serial.println(value); } //メインループ*********************************************** void loop() { if(wifi_mode ==1 ){ HTTP_Responce(); yield();//これは重要!!これがないと動作しない。 }else{ speed_display(); } } //**********************Server-Sent Events レスポンス関数************** void HTTP_Responce() { client = server.available();//クライアント生成は各関数内でしか実行できないので注意 while(client.status()!=CLOSED){ String req = client.readStringUntil('\r'); if (req.indexOf("GET / HTTP") != -1){//ブラウザからリクエストを受信したらこの文字列を検知する Serial.print(req); //ブラウザからのリクエストテキストを残らず読み込む while( client.available() ){ req = client.readStringUntil('\r'); Serial.print(req); yield(); } String str; //-------ここからHTTPレスポンスのHTMLとJavaScriptコード str = "HTTP/1.1 200 OK\r\n"; str += "Content-Type:text/html\r\n"; str += "Connection:close\r\n\r\n";//1行空行が必要 str += "\r\n"; str += "\r\n"; str += "
\r\n"; str += "Speed Server Sync
\r\n"; str += "ESP-WROOM-02(ESP8266)
Speed Meter

\r\n"; str += "\r\n"; str += "
Event wait
\r\n"; str += ""; str += "\r\n"; delay(1000);//1秒待ってレスポンスをブラウザに送信 client.print(str); delay(1);//これが重要!これが無いと切断できないかもしれない。 str = ""; SSE_on = true;//Server-Sent Event 設定終了フラグ client.stop(); Serial.println("\nGET HTTP client stop--------------------"); req =""; SSE_Responce(); }else if(req != ""){ delay(1); client.stop(); delay(1); client.flush(); } req =""; yield(); } } //**************Server-Sent Events データ送信関数**************************** void SSE_Responce(){ //HTTPレスポンス1度目を送信したら、すぐにブラウザから2回目のGETリクエストが来る while(SSE_on == true){//無限ループ client = server.available(); while(client.status()!=CLOSED){ String req = client.readStringUntil('\r'); if(req.indexOf("GET") != -1){//2回目のGETを検知したらServer-Sent Eventsレスポンス送信 Serial.println("GET in--------------------"); Serial.print(req); while(req.indexOf("Accept-Language") == -1){ req = client.readStringUntil('\r'); Serial.print(req); } if(SSE_on == true){ Serial.println("\nsse responce send--------------------"); String sse_resp; //ストリーム配信をブラウザが認識するためのレスポンス sse_resp = "HTTP/1.1 200 OK\r\n"; sse_resp += "Content-Type:text/event-stream\r\n";//SSE使用時に必ずサーバー側からブラウザへこれを返す sse_resp += "Cache-Control:no-cache\r\n"; sse_resp += "\r\n";//必ずこの空行が必要 client.print(sse_resp); delay(3000);//ここの秒数はもう少し少なくても問題ない Serial.println(sse_resp); String sse_data; Serial.println("sse data send--------------------"); LastTime = millis(); while(client.status()!=CLOSED){//Event Sourceデータの無限ループストリーム送信 speed_display(); //速度ブラウザー表示 sse_data = "event:msg_1\n";//ブラウザへ送るeventを発生させて改行コードをつける sse_data += "data:"; sse_data += String(sokudo);//data:の後に送りたいデータをつける sse_data += " km/h"; sse_data += "\n\n";//イベントを発生させるためには必ず改行コード2回連続をつける client.print(sse_data); sse_data = ""; yield(); } delay(1); client.stop(); delay(1); client.flush(); Serial.println("Client.Stop-----------------"); Serial.println(); display.clearDisplay(); // Clear the buffer. display.display(); SSE_on = false; break; } } req = ""; yield(); } yield(); } } void speed_display(){ lastvalue = value; delay(423); //0.423秒ごとにスピード測定 HOは389 //sokudo = (lastvalue-value)*288/340; sokudo = abs(lastvalue-value)*2; //速度モニター表示 Serial.print ("sokudo "); Serial.println(sokudo); // display.clearDisplay(); // Clear the buffer. display.setTextSize(4); display.setTextColor(WHITE); display.setCursor(30,10); display.print(sokudo); display.setCursor(80,50); display.setTextSize(2); display.println("km/h"); display.display(); //delay(2000); }