2022年1月29日土曜日

esp32④(doremi,pyispy3, spiffs,softAp,cp210x,uart/uno)

ESP32 Arduino開発 #3 PWM制御|ブザーでドレミファソラシドを鳴らす - イーテック開発ブログ (e-tecinc.co.jp)

https://wak-tech.com/archives/923 も参考になる spiffsも応用されていた

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

"exec: "python": executable file not found in $PATH - Stack Overflow

sudo ln -s /usr/bin/python3 /usr/bin/python これでpython is python3となってエラがでなくなった

--------------------------------------------------------------

https://github.com/me-no-dev/ESPAsyncWebServer and

https://github.com/me-no-dev/AsyncTCP をライブラリ入れて

https://wak-tech.com/archives/1589#ESPAsyncWebServer を成功した

------------- soft access point on esp32 ---------

#include <WiFi.h>


const char ssid[] = "ESP32AP-WiFi";

const char pass[] = "esp32apwifi";

const IPAddress ip(192,168,30,3);

const IPAddress subnet(255,255,255,0);


const char html[] =

"<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>\

<style>input {margin:8px;width:80px;}\

div {font-size:16pt;color:red;text-align:center;width:400px;border:groove 40px orange;}</style>\

<title>WiFi_Car Controller</title></head>\

<body><div><p>Tank Controller</p>\

<form method='get'>\

<input type='submit' name='on' value='on' />\

<input type='submit' name='off' value='off' />\

</form></div></body></html>";


WiFiServer server(80);


void setup()

{

    Serial.begin(115200);


    WiFi.softAP(ssid,pass);

    delay(100);

    WiFi.softAPConfig(ip,ip,subnet);


    IPAddress myIP = WiFi.softAPIP();


    pinMode(0, OUTPUT);

    delay(10);


    server.begin();


    Serial.print("SSID: ");

    Serial.println(ssid);

    Serial.print("AP IP address: ");

    Serial.println(myIP);

    Serial.println("Server start!");


}


void loop(){

    WiFiClient client = server.available();


    if (client) {

        String currentLine = "";

        Serial.println("New Client.");


        while (client.connected()) {

            if (client.available()) {

                char c = client.read();

                Serial.write(c);

                if (c == '\n') {

                    if (currentLine.length() == 0) {

                        client.println("HTTP/1.1 200 OK");

                        client.println("Content-type:text/html");

                        client.println();


                        client.print(html);

                        client.println();

                        break;

                    } else {

                        currentLine = "";

                    }

                } else if (c != '\r') {

                    currentLine += c;

                }


                if (currentLine.endsWith("GET /?on")) {

                    

                    digitalWrite(0, HIGH);

                    

                }

                if (currentLine.endsWith("GET /?off")) {

                

                    digitalWrite(0, LOW);

                }

            }

        }

        client.stop();

        Serial.println("Client Disconnected.");

    }

}

------------------------------------------------------------------------------

CP210x USB - UART ブリッジ VCP ドライバ - Silicon Labs (silabs.com)

cp210x vcp windowsよりインストする(windows10でusbが!のとき)

------------------------------------------------------------------------

arduinoとは教科書どうりだった

https://qiita.com/suruseas/items/14ae3c7514775f0b1fc4 手持ちのUSBシリアルで

ubuntuのgtktermと交信成功 dev/tty-usbを選択! Gnd共通化!

2022年1月27日木曜日

raspico③ 基本のled,pwm,button-irq,lm61

内部でなく外部のLEDの操作

ラズパイ4対応 カラー図解 最新 Raspberry Piで学ぶ電子工作: 本書の電子工作パーツをRaspberry Pi Picoで利用する (raspibb1a.blogspot.com)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

【Raspberry Pi Pico】DCモーターをモータードライバで制御する | メタエレ実験室 (hellobreak.net) これにもPWMが載っていた

 Raspberry Pi PicoでMicroPythonでPWM信号でスピーカーでメロディー演奏 - Qiita

from machine import Pin, PWM, Timer

speaker = PWM(Pin(17, Pin.OUT)) # スピーカーを接続しているGPIO(この例では17番)を作成し、それをPWM()へ渡す

led_onboard = Pin(25, Pin.OUT) # 基板上のLEDを光らせたいのでGPIO25作成

# 使用する音の周波数を宣言しておく。ピタゴラスイッチは低いラ~高いドまでの音を使う

A4 = 440

B4 = 493.883

C5 = 523.251

C5s= 554.365

D5 = 587.330

E5 = 659.255

F5 = 698.456

F5s= 739.989

G5 = 783.991

A5 = 880

B5 = 987.767

C6 = 1046.502


# bps = 6.4 # 原曲128bpm / 60秒 = 2.1333...bps * 3連符 = 6.4bps

mspb = 156 # 6.4bpsの逆数 = 0.156ms これが8分3連符ひとつ分の音の長さ、音の間隔となる

# ピタゴラスイッチのメロディーを配列で作成。1要素が8分3連符ひとつ分の音の長さになる。0は無音(休符)

melody = [D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,0,B4,C5,0,C5s,D5,0,0,D5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,A4,A4,A4,A4,A4,A4,A4,A4,0,0,F5,E5,0,E5,F5s,E5,F5s,G5,G5,G5,D5,0,B4,C5,0,C5,D5,C5s,D5,B4,B4,B4,0,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5,0,0,0,0,0,0,0,0,0,0,0,0,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5]

i = 0

# 音を鳴らすためのコールバック関数

def beat(timer):

    global melody

    global led_onboard

    global i

    global speaker


    if i >= len(melody): # メロディーを最後まで演奏し終えたら

        speaker.deinit() # スピーカーのPWMを破棄して

        led_onboard.value(0) # LEDを消して

        timer.deinit() # タイマーを破棄して終了


    elif int(melody[i]) == 0: # メロディー音が0、つまり無音(休符)の場合

        speaker.duty_u16(0) 

        # PWMのDutyを0とすることで波形は出力されずLOWとなり、音は出ない

        led_onboard.value(0) # LEDを消す


    else:

        speaker.freq(int(melody[i] + 0.5))

 # PWMの周波数を次のメロディー音の周波数に変更する。

#  整数で渡す必要があるので、+0.5してから小数点以下切り捨て(thanks @naohiro2g)

   speaker.duty_u16(0x8000)

  # PWMのDutyを50%に戻し音を出す。Dutyは0~0xFFFF=65535までの間の値で設定

        led_onboard.value(1) # LEDを光らせる

    i += 1 # メロディーを次に進めて終わり


# 8分3連符の間隔でコールバックを呼ぶタイマーを作成し、メロディースタート

tim = Timer()

tim.init(period=mspb, mode=Timer.PERIODIC, callback=beat)

-------------------------------------------------

Micro Python の書き方(ボタン割り込み) - 自由に工作中 (hatenablog.com)

machine import Pin
import time

# ピンの入出力設定
BUTTON_PIN = 8
button = Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)

LED_PIN = 21
led = Pin(LED_PIN, Pin.OUT)

# 関数定義
def callback(p):
    led.value(1)
    time.sleep(1)

def ledoff():
    led.value(0)
    time.sleep(1)

# Pin.IRQ.Falling call callback
button.irq(trigger=Pin.IRQ_FALLING, handler=callback)

while True:
    ledoff()

----------------------------------------------------------------------------

Raspberry Pi PicoにLCD(AQM0802-PCA9515)と温度センサー(LM61CIZ)をつないで温度を表示 - Qiita

2022年1月22日土曜日

php7 and sqlite3/paiza cloud

php -S localhost:8000 router.php(or index.php at public_html) on paiza cloud

(no apache, php and mysql)

 ---------------------------------------------------

https://www.php.net/manual/ja/sqlite3.open.php を参照したが

https://laboradian.com/how-to-use-sqlite-from-php/#3_PHP_SQLite  も参考にできる

<?php/**
 * SQLite3 クラスを継承して __construct を変更し、
 * open メソッドで DB を初期化します
 */
class MyDB extends SQLite3
{
    function 
__construct()
    {
        
$this->open('mysqlitedb.db');
    }
}

$db = new MyDB();

$db->exec('CREATE TABLE foo (bar STRING)');
$db->exec("INSERT INTO foo (bar) VALUES ('This is a test')");

$result $db->query('SELECT bar FROM foo');
var_dump($result->fetchArray());
?>
 add a not
--------------------------------------------------------------------------------------------

add a notehttps://www.php.net/manual/ja/features.commandline.webserver.php

 にbuitin-serverが詳しい
----------------------------------- paiza ----------------------------------

2022年1月15日土曜日

DCmotorDriverPedia

------------dc-----------l293d---------------------------------------------

 L293Dは、モータ電源4.5v以上なので 多分電源電圧を単3x4を用意すれば

他のマイコンでもいけるだろう https://omoroya.com/arduino-lesson26/ も参照
---dc---------microbit only-----------------------------------------------------------
mic専用のmotor driver moduleで2個すんなりうごいた ただしmotorはFA130
http://www.micro-bit.info/archives/1141 
 keystudio ks0308 dc motor driver module モータとMICのGNDは別 
TB6612FNG がもとになっており、くわしくは以下のサイト
https://qiita.com/MedakanoGakko/items/e9624c3fa45e40b0425e 

ーーーdcーーーーTB67H450 single motor driver ーーーー
https://akizukidenshi.com/catalog/g/gK-14753/
VREFは3.3でも5でもいいみたいだ
このサイト情報は重要 電源電圧4.5V以上だった 単3x4が必要! L293Dも同一だろう

ーーーーーーdc---drv8835ーーーー

DRV8835でもGNDはマイコンと共通化、モータ電源が2〜7vとなっており、

espr2でも動いた! esprのピン配置は上下よく間違える! 注意注意

https://www.petitmonte.com/robot/howto_dc_motor_drv8835.html を参考にする

mode(11ピン)をGNDにおとしてゼロにしている、あとは9,10ピンをPWMし正逆を制御

プチモンテの方法(PWMっぽい)ではうごかんので以下のようにする

const int MORTOR1_PIN = 1;

const int MORTOR2_PIN = 0;

void setup() {

  // put your setup code here, to run once:

  pinMode(MORTOR1_PIN,OUTPUT);

  pinMode(MORTOR2_PIN,OUTPUT);

}

void loop() {

  // put your main code here, to run repeatedly:

  digitalWrite(MORTOR1_PIN,HIGH);

  digitalWrite(MORTOR2_PIN,LOW);

  delay(2000);

  digitalWrite(MORTOR1_PIN,HIGH);

  digitalWrite(MORTOR2_PIN,HIGH);

  delay(2000);

}



---dc-------------tc78h653ftg------------------結局壊した-----------------------------------------

以下をすると48以上ではおかしくなる逆起電力の問題か?正転・停止・逆転・停止で安定
モータだけならそれでいいが、ギアボックスの場合speeds100以上でないとトルクが出ん
ので音はすれど動かず! pwm方式の盲点だな。

  1. // 回転速度(35-255)
  2. // ※値が大きいほど高速,余りにも小さい値は回転しません。
  3. const uint8_t speeds = 48;

  4. void setup() {
  5. Serial.begin(9600);
  6. }
  7. void loop() {
  8. // 正転(回転)
  9. Serial.println("正転");
  10. analogWrite(10,speeds);
  11. analogWrite(11,0);
  12. delay(1000);
  13.  
  14. // 逆転(逆回転)
  15. Serial.println("逆転");
  16. analogWrite(10,0);
  17. analogWrite(11,speeds);
  18. delay(1000);
  19. // ブレーキ
  20. Serial.println("ブレーキ");
  21. analogWrite(10,speeds);
  22. analogWrite(11,speeds);
  23. delay(1000);
  24. }



https://coskxlabsite.stars.ne.jp/html/for_students/M5Stack/MotorDrivingDemo2/MotorDrivingDemo2.html を参考に TC78H653FTGをraspicoで動かした!
 上図にあるようにモータとマイコンのGNDは別,共通にしてはいけない!

【Raspberry Pi Pico】DCモーターをモータードライバで制御する | メタエレ実験室 (hellobreak.net)  デジタルオンオフとPWMの2種のコードがあった  tc78でもOKだった

import machine
import utime

IN1 = machine.Pin(1, machine.Pin.OUT)
IN2 = machine.Pin(2, machine.Pin.OUT)

while True:
    # 正転
    IN1.value(1)
    IN2.value(0)
    utime.sleep(2)
    
    # ブレーキ
    IN1.value(1)
    IN2.value(1)
    utime.sleep(2)
from machine import PWM, Pin
import utime

IN1 = PWM(Pin(1))
IN2 = PWM(Pin(2))
IN1.freq(100)
IN2.freq(100)

max_duty = 65025

while True:
    # 正転
    IN2.duty_u16(0)
    for i in range(50, 100):
        IN1.duty_u16(int(max_duty*i*0.01))
        utime.sleep(0.1)
        
    # ブレーキ
    IN1.duty_u16(max_duty)
    IN2.duty_u16(max_duty)
    utime.sleep(2)


2022年1月7日金曜日

firebase (2種認証:前者esp32okでesprがstack over、後者esp32/espr both OK)

 https://github.com/mobizt/Firebase-ESP32/blob/master/examples/Basic/Basic.ino

レガシー方式をデコメントして、コールバック方式はコメント化した 

mail-address,password はそのままいれた api-keyとdatabase-secretは別物

前者はproject setting,後者はservice-accountsで参照できる

esp32 無事に成功した esp8266 不可解なエラー

// https://github.com/mobizt/Firebase-ESP32/blob/master/examples/Basic/Basic.ino

#if defined(ESP32)

#include <WiFi.h>

#include <FirebaseESP32.h>

#elif defined(ESP8266)

#include <ESP8266WiFi.h>

#include <FirebaseESP8266.h>

#endif

//Provide the token generation process info.

#include <addons/TokenHelper.h>

//Provide the RTDB payload printing info and other helper functions.

#include <addons/RTDBHelper.h>

#define WIFI_SSID ""

#define WIFI_PASSWORD ""

/*  

For the following credentials, see examples/Authentications/SignInAsUser/EmailPassword/EmailPassword.ino 

*/

/* 2. Define the Project API Key , database secretsと混同しない */

#define API_KEY ""

/* 3. Define the RTDB URL */

#define DATABASE_URL "https://iot-rtd-default-rtdb.firebaseio.com" 

//<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app

/* 4. Define the user Email and password that alreadey registerd or added in your project */

#define USER_EMAIL ""

#define USER_PASSWORD ""

//Define Firebase Data object

FirebaseData fbdo;

FirebaseAuth auth;

FirebaseConfig config;

unsigned long sendDataPrevMillis = 0;

unsigned long count = 0;

void setup()

{

  Serial.begin(115200);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to Wi-Fi");

 while (WiFi.status() != WL_CONNECTED)

   {   Serial.print(".");

     delay(300);

  }

 Serial.println();

Serial.print("Connected with IP: ");

Serial.println(WiFi.localIP());

Serial.println();

  Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);

  /* Assign the api key (required) */

  config.api_key = API_KEY; 

  /* Assign the user sign in credentials */

  auth.user.email = USER_EMAIL;

  auth.user.password = USER_PASSWORD;

  /* Assign the RTDB URL (required) */

  config.database_url = DATABASE_URL;

  /* Assign the callback function for the long running token generation task */

  //config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

  // 上の1行をコメントアウトした

  //Or use legacy authenticate method 以下のlegacy_tokenがdatabase secretsだった

  config.database_url = DATABASE_URL;

 config.signer.tokens.legacy_token = "";

  // 上の2行をデコメントした

  //To connect without auth in Test Mode, see Authentications/TestMode/TestMode.ino

  //////////////////////////////////////////////////////////////////////////////////////////////

  //Please make sure the device free Heap is not lower than 80 k for ESP32 

// and 10 k for ESP8266, otherwise the SSL connection will fail. 

// このためか、esp8266では失敗した

  //////////////////////////////////////////////////////////////////////////////////////////////

  Firebase.begin(&config, &auth);

  //Comment or pass false value when WiFi reconnection will 

// control by your code or third party library

Firebase.reconnectWiFi(true);

  Firebase.setDoubleDigits(5);

  /* Timeout options. 時間切れを設定するもろもろ setupの最後までつづく

  //WiFi reconnect timeout (interval) in ms (10 sec - 5 min) when WiFi disconnected.

  config.timeout.wifiReconnect = 10 * 1000;

  //Socket connection and SSL handshake timeout in ms (1 sec - 1 min).

  config.timeout.socketConnection = 10 * 1000;

  //Server response read timeout in ms (1 sec - 1 min).

  config.timeout.serverResponse = 10 * 1000;

  //RTDB Stream keep-alive timeout in ms (20 sec - 2 min) when no server's keep-alive event data received.

  config.timeout.rtdbKeepAlive = 45 * 1000;

  //RTDB Stream reconnect timeout (interval) in ms (1 sec - 1 min) when RTDB Stream closed and want to resume.

  config.timeout.rtdbStreamReconnect = 1 * 1000;

  //RTDB Stream error notification timeout (interval) in ms (3 sec - 30 sec). It determines how often the readStream

  //will return false (error) when it called repeatedly in loop.

  config.timeout.rtdbStreamError = 3 * 1000;

  Note:

  The function that starting the new TCP session i.e. first time server connection or previous session was closed, the function won't exit until the 

  time of config.timeout.socketConnection.

 You can also set the TCP data sending retry with

  config.tcp_data_sending_retry = 1;

  */

}

void loop()

{ 

  if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0)) // 更新条件の確認

  {

    sendDataPrevMillis = millis();

    Serial.printf("Set bool... %s\n", Firebase.setBool(fbdo, F("/test/bool"), count % 2 == 0) ? "ok" : fbdo.errorReason().c_str());

    Serial.printf("Get bool... %s\n", Firebase.getBool(fbdo, FPSTR("/test/bool")) ? fbdo.to<bool>() ? "true" : "false" : fbdo.errorReason().c_str());

        bool bVal; // for reference later....

    Serial.printf("Get bool ref... %s\n", Firebase.getBool(fbdo, F("/test/bool"), &bVal) ? bVal ? "true" : "false" : fbdo.errorReason().c_str());

    Serial.printf("Set int... %s\n", Firebase.setInt(fbdo, F("/test/int"), count) ? "ok" : fbdo.errorReason().c_str());

    Serial.printf("Get int... %s\n", Firebase.getInt(fbdo, F("/test/int")) ? String(fbdo.to<int>()).c_str() : fbdo.errorReason().c_str());

    int iVal = 0; // for reference later

    Serial.printf("Get int ref... %s\n", Firebase.getInt(fbdo, F("/test/int"), &iVal) ? String(iVal).c_str() : fbdo.errorReason().c_str());

    Serial.printf("Set float... %s\n", Firebase.setFloat(fbdo, F("/test/float"), count + 10.2) ? "ok" : fbdo.errorReason().c_str());

    Serial.printf("Get float... %s\n", Firebase.getFloat(fbdo, F("/test/float")) ? String(fbdo.to<float>()).c_str() : fbdo.errorReason().c_str());

    Serial.printf("Set double... %s\n", Firebase.setDouble(fbdo, F("/test/double"), count + 35.517549723765) ? "ok" : fbdo.errorReason().c_str());

    Serial.printf("Get double... %s\n", Firebase.getDouble(fbdo, F("/test/double")) ? String(fbdo.to<double>()).c_str() : fbdo.errorReason().c_str());

    Serial.printf("Set string... %s\n", Firebase.setString(fbdo, F("/test/string"), "Hello World!") ? "ok" : fbdo.errorReason().c_str());

    Serial.printf("Get string... %s\n", Firebase.getString(fbdo, F("/test/string")) ? fbdo.to<const char *>() : fbdo.errorReason().c_str());

    //For the usage of FirebaseJson, see examples/FirebaseJson/BasicUsage/Create_Edit_Parse.ino

    FirebaseJson json;

    if (count == 0)

    {

  json.set("value/round/" + String(count), F("cool!"));

  json.set(F("vaue/ts/.sv"), F("timestamp"));

  Serial.printf("Set json... %s\n", Firebase.set(fbdo, F("/test/json"), json) ? "ok" : fbdo.errorReason().c_str());

    }

    else

    {

      json.add(String(count), "smart!");

      Serial.printf("Update node... %s\n", Firebase.updateNode(fbdo, F("/test/json/value/round"), json) ? "ok" : fbdo.errorReason().c_str());

    }

    Serial.println();

    //For generic set/get functions.

    //For generic set, use Firebase.set(fbdo, <path>, <any variable or value>)

    //For generic get, use Firebase.get(fbdo, <path>).

    //And check its type with fbdo.dataType() or fbdo.dataTypeEnum() and

    //cast the value from it e.g. fbdo.to<int>(), fbdo.to<std::string>().

    //The function, fbdo.dataType() returns types String e.g. string, boolean,

    //int, float, double, json, array, blob, file and null.

    //The function, fbdo.dataTypeEnum() returns type enum (number) e.g. fb_esp_rtdb_data_type_null (1),

    //fb_esp_rtdb_data_type_integer, fb_esp_rtdb_data_type_float, fb_esp_rtdb_data_type_double,

    //fb_esp_rtdb_data_type_boolean, fb_esp_rtdb_data_type_string, fb_esp_rtdb_data_type_json,

    //fb_esp_rtdb_data_type_array, fb_esp_rtdb_data_type_blob, and fb_esp_rtdb_data_type_file (10)

  count++;

  } // end of if  (count==0) 

}  // end of looop()


/// PLEASE AVOID THIS ////


//Please avoid the following inappropriate and inefficient use cases

/** * 

 * 1. Call get repeatedly inside the loop without the appropriate timing for execution provided e.g. millis() or conditional checking,

 * where delay should be avoided.


 * 


 * Everytime get was called, the request header need to be sent to server which its size depends on the authentication method used, 


 * and costs your data usage.


 * 


 * Please use stream function instead for this use case.


 * 


 * 2. Using the single FirebaseData object to call different type functions as above example without the appropriate 


 * timing for execution provided in the loop i.e., repeatedly switching call between get and set functions.


 * 


 * In addition to costs the data usage, the delay will be involved as the session needs to be closed and opened too often


 * due to the HTTP method (GET, PUT, POST, PATCH and DELETE) was changed in the incoming request. 


 * 


 * 


 * Please reduce the use of swithing calls by store the multiple values to the JSON object and store it once on the database.


 * 


 * Or calling continuously "set" or "setAsync" functions without "get" called in between, and calling get continuously without set 


 * called in between.


 * 


 * If you needed to call arbitrary "get" and "set" based on condition or event, use another FirebaseData object to avoid the session 


 * closing and reopening.


 * 


 * 3. Use of delay or hidden delay or blocking operation to wait for hardware ready in the third party sensor libraries, together with stream functions e.g. Firebase.RTDB.readStream and fbdo.streamAvailable in the loop.


 * 


 * Please use non-blocking mode of sensor libraries (if available) or use millis instead of delay in your code.


 * 


 * 4. Blocking the token generation process.


 * 


 * Let the authentication token generation to run without blocking, the following code MUST BE AVOIDED.


 * 


 * while (!Firebase.ready()) <---- Don't do this in while loop


 * {


 *     delay(1000);


 * }


 * 


 */

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー


#if defined(ESP32)
#include <WiFi.h>
#include <FirebaseESP32.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <FirebaseESP8266.h>
#endif

//Provide the RTDB payload printing info and other helper functions.
#include <addons/RTDBHelper.h>

/* 1. Define the WiFi credentials */
#define WIFI_SSID ""
#define WIFI_PASSWORD ""
/* 3. Define the RTDB URL */

#define DATABASE_URL "https://iot-rtd-default-rtdb.firebaseio.com" // 自分のそれに書き換え必要
/* 2. If work with RTDB, define the RTDB URL and database secret */

#define DATABASE_SECRET "RqUMroVs0CPP3jHSQHPNN9EhNxtlEgs0Q949UT6o" //自分のそれに書き換え必要

/* 3. Define the Firebase Data object */
FirebaseData fbdo;

/* 4, Define the FirebaseAuth data for authentication data */
FirebaseAuth auth;

/* Define the FirebaseConfig data for config data */
FirebaseConfig config;

unsigned long dataMillis = 0;
int count = 0;

void setup()
{

    Serial.begin(115200);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting to Wi-Fi");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);

    /* Assign the certificate file (optional) */
    //config.cert.file = "/cert.cer";
    //config.cert.file_storage = StorageType::FLASH;

    /* Assign the database URL and database secret(required) */
    config.database_url = DATABASE_URL;
    config.signer.tokens.legacy_token = DATABASE_SECRET;

    Firebase.reconnectWiFi(true);

    /* Initialize the library with the Firebase authen and config */
    // Firebase.begin(&config, &auth);

    //Or use legacy authenticate method
    Firebase.begin(DATABASE_URL, DATABASE_SECRET); //ここでリセットがかかるようだ
}

void loop()
{
    if (millis() - dataMillis > 5000)
    {
        dataMillis = millis();
        Serial.printf("Set int... %s\n", Firebase.setInt(fbdo, "/test/int", count++) ? "ok" : fbdo.errorReason().c_str());
        Serial.printf("Get int... %s\n", Firebase.getInt(fbdo, F("/test/int")) ? String(fbdo.to<int>()).c_str() : fbdo.errorReason().c_str());

    }
}

2022年1月2日日曜日

mqtt service (esp32 and esp8266)

ーーーーーーーicecream free server ーーーーーーーーーーーーーーーーーーーーーーー

MQTTについてのまとめ — そこはかとなく書くよん。 ドキュメント (tdoc.info)

 https://take6shin-tech-diary.com/mqtt/ localでmqttブローカをたちあげる

一つの窓でブローカ開始してPub、もう一つの窓でSub 

Subは自動ダウンなし 購読しっぱなし Pubは、一回の出版ごとに自動ダウン

MQTTbrokerを使ってみる(その1)準備編|ゆう|note 無料のbroker記事

MQTTbrokerを使ってみる(その2)通信編|ゆう|note 同上

username(*)はfseigojpなどといれる client_idはランダムに出されている

username(no*)にicecreamといれ mqttxでmqtt.uko.jpにコネクト!

まずtopic名をきめてsubscribeしておく あとは、それに対してpublishするだけ

-------------node.js mqtt -------------------------test.mosquitto.org--------------------------------------

https://blog.mitsuruog.info/2015/02/what-mqtt.html を参考に

mqttxでanonymous接続してからsubscriptionでpresenceをつくると

node hello_mqtt.js のやりとりが観察できた

----------------bash mqtt ----public-mqtt5-broker----------------------------------------------------

https://qiita.com/ekzemplaro/items/0a03a96c2f5a5ba2ae55

------------------esp8266 for public mqtt server -------

コードではpublishしてsubscribeしてますが、publishは成功しませんでした
mqttxというclient appにesp8266-clientというusernameで入り、esp8266/testというtopicを
つくって適当なメッセージをpublishすると、arduinoのシリアルモニタで観察できました
今週末は、別のアルディーノでpublishして、同様になるか実験。。。

その後、次のように、したらうまくいった(セットアップでサブして、ループでパブ)
esp32でも同じだと思う ただ現実には自分でなげてうけるのは意味がない 
サブとパブは、本来別々のマイコンでうごくべき!

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char *ssid = ""; // Enter your WiFi name
const char *password = "";  // Enter WiFi password
const char *mqtt_broker = "broker.emqx.io";
const int mqtt_port = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
    // Set software serial baud to 115200;
    Serial.begin(115200);
    // connecting to a WiFi network
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi..");
    }
    Serial.println("Connected to the WiFi network");
    //connecting to a mqtt broker
    client.setServer(mqtt_broker, mqtt_port);
    client.setCallback(callback);
    while (!client.connected()) {
        Serial.println("Connecting to public emqx mqtt broker.....");
        if (client.connect("esp8266-client")) {
            Serial.println("Public emqx mqtt broker connected");
        } else {
            Serial.print("failed with state ");
            Serial.print(client.state());
            delay(2000);
        }
    }
    // publish and subscribe
   
    client.subscribe("esp8266/test");
}

void callback(char *topic, byte *payload, unsigned int length) {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    Serial.print("Message:");
    for (int i = 0; i < length; i++) {
        Serial.print((char) payload[i]);
    }
    Serial.println();
    Serial.println("-----------------------");
}

void loop() {
    client.publish("esp8266/test", "hello emqx");
    client.loop();
    delay(1000);
}

-ーーーーーーesp32でフリーのMQTTを利用するーーtest.mosquitto.orgーーー

https://programresource.net/2020/05/23/3332.html : パブサブOK)

mqttxでanonymous loginしてESP32/TEST/TOPICをサブスクライブしておき

同時にESP32/TEST/TOPICをパブリッシュするようにしておく

あとは以下のコードを実行すると、コードからパブリッシュされるtest publishが

自動的にコードのサブスクライブを呼ぶ またmqttxでパブリッシュしたときは

それが自動的にコードのサブスクライブを呼ぶ

#include <PubSubClient.h>

#include <WiFi.h>


char ssid[] = "";

char pass[] = "";


const char* mqtt_server = "test.mosquitto.org";

const char* mqtt_topic = "ESP32/TEST/TOPIC";


WiFiClient mqttClient;

PubSubClient client(mqttClient);

char mqtt_clientid[32]; // uniqueである必要がある


void callback(char* topic, byte* payload, unsigned int length) {

    char payload_ch[32];

    int chlen = min(31, (int)length);

    memcpy(payload_ch, payload, chlen);

    payload_ch[chlen] = 0; // payload_chがc言語で扱える文字列となる

    Serial.println(payload_ch);

} //ここはsubscribeで起動されるコード片



void wait_mqtt() {

    if (!client.connected()) {

        Serial.print("Waiting MQTT connection...");

        while (!client.connected()) { // 非接続のあいだ繰り返す

            if (client.connect(mqtt_clientid)) { // ここでuniqueなmqtt_clientidで接続する

                client.subscribe(mqtt_topic); // ここで購読がセットされる

            } else {

                delay(2000);

            }

        }

        Serial.println("connected");

    }

}



void setup() {

    Serial.begin(115200);

    Serial.print("connecting wifi");

    WiFi.mode(WIFI_STA); // station mode 

    if (String(WiFi.SSID()) != String(ssid)) {

        WiFi.begin(ssid, pass);


    }

    WiFi.setSleep(false); // sleep omitted? 多分

    while (WiFi.status() != WL_CONNECTED) {

        delay(500);

        Serial.print(".");

    }

    Serial.println("connected");

    byte mac_addr[6];

    WiFi.macAddress(mac_addr);

    sprintf(mqtt_clientid, "ESP32CLI_%02x%02x%02x%02x%02x%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);

    // ここでマックアドレスを用いてuniqueなclient_idを作成

    client.setServer(mqtt_server, 1883); // websocketでない場合のポート番号は1883

    client.setCallback(callback);

}


void loop() {

    int c ;

    wait_mqtt();

    client.loop();

    client.publish(mqtt_topic, "test publish"); //送信はこうで、自動的に購読のcallbackが呼ばれる

    Serial.println("sub");

    delay(1000);

}

ーーーーーabout esp8266 -- local mosquitto broker --一番現実的かも

https://tiagohorta1995.medium.com/mosquitto-mqtt-broker-and-esp8266-communcation-in-6-easy-steps-5ea0efae5a10 でローカルのmqtt brokerを

うごかしての記録 mossquitto.confを自作して再起動して成功  conf :: 以下の2行だけ

listener 1883

allow_anonymous true

アルディーノのコードはこれ やはりpublishとsubscribeは同居できんかった

別窓からパブしてOKだった

#include <ESP8266WiFi.h>

#include <PubSubClient.h>

// WiFi 

const char *ssid = "184F32CF8BF3-2G"; // Enter your WiFi name

const char *password = "2215085363556";  // Enter WiFi password

// MQTT Broker

const char *mqtt_broker = "192.168.3.9"; // get by hostname -I 

const char *topic = "test/topic";

const int mqtt_port = 1883;

WiFiClient espClient;

PubSubClient client(espClient);

void setup() {

 // Set software serial baud to 115200;

 Serial.begin(115200);

 

 // connecting to a WiFi network

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

  delay(500);

  Serial.println("Connecting to WiFi..");

 }

 

 Serial.println("Connected to the WiFi network");

 

 //connecting to a mqtt broker

 client.setServer(mqtt_broker, mqtt_port);

 client.setCallback(callback);

 

 while (!client.connected()) {

 String client_id = "esp8266-client-";

 client_id += String(WiFi.macAddress());

 

 Serial.printf("The client %s connects to mosquitto mqtt broker\n", client_id.c_str());

 

 if (client.connect(client_id.c_str())) {

  Serial.println("Public emqx mqtt broker connected");

 } else {

  Serial.print("failed with state ");

  Serial.print(client.state());

  delay(2000);

 }

}

 

 // publish and subscribe

 client.publish(topic, "Hello From ESP8266!");

 client.subscribe(topic);

}

void callback(char *topic, byte *payload, unsigned int length) {

 Serial.print("Message arrived in topic: ");

 Serial.println(topic);

 Serial.print("Message:");

 

 for (int i = 0; i < length; i++) {

  Serial.print((char) payload[i]);

 }

 

 Serial.println();

 Serial.println(" - - - - - - - - - - - -");

}

void loop() {

 client.loop();

}