ESP32のSerialライブラリ [ESP32]
ESP32は標準のSerialがあるけれど、それ以外にJPEGカメラとサーモセンサー(共にシリアルインタフェース)を接続する為に、2つのSerialを追加して使用している。
そうすると、わりと高い頻度で追加したSerialが止まってしまう困った現象を起こしていた。
でまぁ、困ったのでgithubを見るとSerial廻りとか割り込み廻りの更新が9月20日くらいに行われているので、そのバージョンを適用してみた。
結果、いまのところ順調である。
やれやれ、、、
そうすると、わりと高い頻度で追加したSerialが止まってしまう困った現象を起こしていた。
でまぁ、困ったのでgithubを見るとSerial廻りとか割り込み廻りの更新が9月20日くらいに行われているので、そのバージョンを適用してみた。
結果、いまのところ順調である。
やれやれ、、、
ESP32のSDライブラリ [ESP32]
ごくまれではあるけれど、ディレクトリを取ったりファイルにアクセスしようとすると、「そんな物は存在しない」と返してきやがる、、、
こんな報告も上がっている。これを対策すれば解消するかどうかは判らない。まあ入れたけど。
とりあえず対処療法として現象が出た場合は以下の処理を入れてみる。ルートディレクトリ上にファイルやディレクトリのエントリーが見つからない時、SDを一旦止めて再度起動。
ホント対処療法だなぁ、、、
こんな報告も上がっている。これを対策すれば解消するかどうかは判らない。まあ入れたけど。
とりあえず対処療法として現象が出た場合は以下の処理を入れてみる。ルートディレクトリ上にファイルやディレクトリのエントリーが見つからない時、SDを一旦止めて再度起動。
if( entryNumber == 0 && strcmp( dirsAndFiles, "/" ) == 0 ) /* is root directory and no entry ? */ { debugPrintln( "******** SD card reopen." ); SD.end(); SD.begin( SD_CARD_SS_PIN, SPI, 8000000, "/SD" ); }
ホント対処療法だなぁ、、、
ESP32のGPIOの割り付けについて調べてみた。 [ESP32]
ESP32、とても多機能で便利ですが、その多機能を少ない端子に多重化されている為に、オリジナルの基板を作成する時に毎回割り当てに悩む、、、
Serial1、2やI2Cは任意のピンに割り当てを可能なのだが、多重化された機能とか、BOOTとか、そもそも全部のGPIO端子が入出力とはならないとかでイマイチ明確にどのピンの割り当て可能なのかすっきりしなかったので、実際に試してみた。
以下にI2Cで使用した場合、Serialで使用した場合、プルアップ or プルダウン、割り込みについて対応表を書いてみた。
もちろん!無保証。
IO0,IO2,IO12の使用は、十分注意して使った方がよろしいでしょう。
※確認は、ESP32 Devkitを使用
※I2Cの確認は、2kΩのプルアップ抵抗を外付けして、100kbpsで試験
※割り込みの確認は、10kΩのプルアップ抵抗とタクトスイッチを外付けして試験
※標準のPULL UP、PULL DOWNの強度は最大で75μA
※GPIOの出力電流の強さは設定可能。標準では20mA。最大で40mA。ええ勿論40mAなんて怖くて試していません
※Any GPIOの対象となるのは上記の周辺以外に、I2S、MCPWM(Motor Control)、LEDC、RC(IRのRemote Control)、HSPI、VSPI(ArduinoのSPIクラスで使用)
※参考
https://trac.switch-science.com/wiki/esp32_tips
MTDIはIO12、MTDOはIO15の事。
※起動時にIO12が1だとBASICが走るのだっけ?
https://hackaday.com/2016/10/27/basic-interpreter-hidden-in-esp32-silicon/
※起動時にIO2が1、つまりI2Cに利用したりUARTの受信に使用するとBOOTモードに入らない
Arduino core for the ESP32 core panic [ESP32]
本当はこの記事では「ESP32 Arduinoはユーザーが排他制御をあまり意識しなくても使えますよ~、楽ですよ~」ってするつもりだったんです。それがですねぇ、この結末、、、
はじまりはESP32 ArduinoでI2Cに関する検索をしていたらツイッターに、「ESP32 Arduinoは排他制御が入っているのでこの結果はおかしい」的なのを見付けて、「ええ!そうなんですか?」ってソースコード(esp32-hal-i2c.c)を見てみました。
あ、有るのう、、、
ちなみに定義されているCONFIG_DISABLE_HAL_LOCKSは何処に有るのか探してみると、esp32\tools\sdk\sdkconfigの中に
# # Arduino Configuration # CONFIG_ENABLE_ARDUINO_DEPENDS=y CONFIG_AUTOSTART_ARDUINO=y CONFIG_DISABLE_HAL_LOCKS=
の様に記述されています。実際にこれが有効なのかどうかは判りませんが、なんとなくCONFIG_DISABLE_HAL_LOCKSの定義には値が設定されていない気がする。
となると
i2c->lock = xSemaphoreCreateMutex();
でI2C用のミューテックスが生成され、排他制御が有効となっていると考えられます。
ちなみにI2C同様にミューテックスが設定されているのは、LEDC、SIGMA-DELTA、SPI、UARTでした。
と言う訳で前回
https://hamayan.blog.so-net.ne.jp/2018-07-11
で実行したプログラムの中から、セマフォに関するコードを抜いて実行してみました。
その結果が冒頭のキャプチャです。
あれぇ???と思っているとArduino core for the ESP32のI2Cの抽象化層がしれっと更新されているので、新しい奴で試してみましたが、やはりカーネルパニックを発生させて再起動します。
片方のタスクの起動時間を100msくらいオフセットしてしまえば、一応は起動直後にカーネルパニックを起こす事は避けられていますが、、、タスク間で同期が必要になりますもんね。
なーんでしょうね?次のバージョンアップに期待ですか。
複数タスクでI2Cを共有する場合、当面はこのやり方の様にユーザーで排他制御を入れた方が安心です。
https://hamayan.blog.so-net.ne.jp/2018-07-11
複数タスクの同時アクセスでカーネルパニックを起こすのがI2Cだけなのか、まだわからない、、、
ESP32 ArduinoでI2Cをマルチタスクで動かす by freeRTOS [ESP32]
I2C接続された2個のBME280をマルチタスクで動かすデモです。
※この話には続きが多分有る!
※ついさっき、Arduino core for the ESP32のI2Cの抽象化層のコードに修正が入った模様。明日、試す。
ここで書いているバージョンのESP32 Arduinoでは確かにI2Cがまともに動きませんでした。
https://hamayan.blog.so-net.ne.jp/2018-06-13-1
多分それ以前のバージョンも、、、
実はつい先日Arduino core for the ESP32が更新されています、、、
https://github.com/espressif/arduino-esp32
はぁぁぁぁ、、、
以下、試験概要
主にI2Cの読み出しでWire.available()が0のまま先に進まない(詳細は不明)感じ。ただこれマルチタスクでやるとなんとなく現象が出やすいだけで、実際には元々I2Cのドライバーがバグっている様な気がする。と言うかまともなドライバーなら排他制御をすればI2Cが問題になるとは思えない。
I2Cのマルチタスク環境下での確認は以下の要領となります。
1.ESP32を1個用意
2.BME280を2個用意
3.2つのBME280をI2Cアドレスをちょっと変えてESP32とI2C接続
4.loopTaskのsetupでloopTask自身の優先度を最大に設定、、、しません
5.loopTaskのsetupでI2Cの排他制御を行うバイナリーセマフォを生成
6.loopTaskのsetupでI2CとBME280の初期化を行う。
7.loopTaskのsetupでAmbientに接続
8.loopTaskのsetupで2つのBME280のそれぞれにI2Cでアクセスする2つのタスクを生成。優先度は同一で低め。つまりloopTaskも含めて3つのユーザータスクが存在する
9.loopTaskのloopでAmbientに、大域変数に保存された2つのBME280の温度、湿度、気圧を送信、グラフ表示を行う。またAmbientに送信する度にカウントアップする値もグラフに表示して、CPUの連続稼働状態のモニターとする。
10.BME280から温度、湿度、気圧を取得するタスクの中では、セマフォを使って排他制御を行いBME280からAD値を取得、実際の温度や湿度や気圧に換算して大域変数に保存。この保存した値を、loopTaskが参照する。
エラー状況を確認
2018年6月13日に入れたバージョンのシリアル出力はこの様にエラー出力を頻発している。
2018年7月11日バージョンのシリアル出力はこの様にエラー出力をしておらず、安定している。
下の図は、2018年7月11日バージョンでAmbientでグラフ化したもの。
ESP32_BME280_Ambient.ino
/****************************************************************************/ /* ESP32 BME280 project for Ambient */ /* Copyright (C) 2018- by hamayan */ /****************************************************************************/ #define __DEBUG__ //#define __RUN_IN_AP_MODE__ #define __RUN_IN_STA_MODE__ #include <WiFi.h> #include "bme280.h" #include "Ambient.h" extern "C" { } /*************************************************************************/ /* prototype and defines. */ /*************************************************************************/ #define BME280_DEFAULT_I2C_ADDRESS 0x76 #define BME280_EXTEND_I2C_ADDRESS 0x77 #define I2C_HERTZ 100000UL #define SCL_PIN 26 /**/ #define SDA_PIN 25 /**/ #define ACT_LED_PIN 100 /* そんな物は無かった */ static void connectWifi(); static void networkInformations(); void IRAM_ATTR onTimerEvery1seconds(); /*************************************************************************/ /* instances and valiables. */ /*************************************************************************/ bme280 bme280_01( BME280_DEFAULT_I2C_ADDRESS ); /* bme280( uint8_t adr ); */ bme280 bme280_02( BME280_EXTEND_I2C_ADDRESS ); /* bme280( uint8_t adr ); */ volatile int pressure01,humidity01,temperature01; volatile int pressure02,humidity02,temperature02; volatile int cpuCounter; WiFiClient client; Ambient ambient; unsigned int ambientChannelId = 0123456789; const char* ambientWriteKey = "abcdefg"; const char* ambientReadKey = "abcdefg"; hw_timer_t *timer1second = NULL; volatile time_t unixTime; /*1970年からの通算秒*/ volatile time_t passedTime; /* from start. */ /*************************************************************************/ /* task prototype defines. */ /*************************************************************************/ enum TASK_IDS { TASK_ID_I2C_TEST01 = 0, TASK_ID_I2C_TEST02, TASK_ID_END }; xTaskHandle taskHandle[ TASK_ID_END ]; volatile SemaphoreHandle_t semaI2C; /* I2Cのセマフォ */ void i2cTestTask01( void *execParam ); void i2cTestTask02( void *execParam ); /*************************************************************************/ /* Wi-Fi defines. */ /*************************************************************************/ const char ssidAP[] = "ESP32_I2C_TEST"; // SSID const char passAP[] = "password"; // password const IPAddress apIP( 0, 0, 0, 0 ); // access point ip address const IPAddress subnet( 255, 255, 255, 0 ); // sub net mask const IPAddress stationIP( 0, 0, 0, 0 ); // station mode static ip address const IPAddress dnsIP( 0, 0, 0, 0 ); // station mode dns ip address const IPAddress gwIP( 0, 0, 0, 0 ); // station mode gateway ip address IPAddress myIpAddress; const char ssidSTA[] = "ssid"; // SSID const char passSTA[] = "password"; // password const char ntpServer[] = "ntp.nict.jp"; /*************************************************************************/ /* setup. */ /*************************************************************************/ void setup() { Serial.begin( 115200 ); Serial.println( "ESP32 I2C Test." ); uint64_t chipid = ESP.getEfuseMac(); //The chip ID is essentially its MAC address(length: 6 bytes). Serial.printf( "ESP32 Chip ID = %04X",(uint16_t)(chipid>>32) ); //print High 2 bytes Serial.printf( "%08X\n",(uint32_t)chipid ); //print Low 4bytes. /* initialize unixTime */ struct tm localTime = {0,0,0,10,4-1,2018-1900,0,0,0}; unixTime = mktime( &localTime ); /* 1second timer interrupt initialize. */ timer1second = timerBegin( 0, 80, true ); timerAttachInterrupt( timer1second, &onTimerEvery1seconds, true ); timerAlarmWrite( timer1second, 1000 * 1000UL, true ); /* 1second timer interrupt start. */ timerAlarmEnable( timer1second ); /* gpio pins configuration, */ initGPIO(); /* display mac address. */ networkInformations(); /* wifi AP open */ connectWifi(); #if defined( __RUN_IN_STA_MODE__ ) /* init and get the time from ntp server. */ Serial.print( "Connecting to NTP server. current time = " ); connectNTP( ntpServer ); Serial.print( stringDataAndTime( NULL, NULL ) ); Serial.println( " ...done." ); #endif /* defined( __RUN_IN_STA_MODE__ ) */ /* configure tasks. */ /* change the task priority to highest. */ // UBaseType_t currentPriority = uxTaskPriorityGet( NULL ); // vTaskPrioritySet( NULL, 24 ); /* Create binary semaphore */ semaI2C = xSemaphoreCreateBinary(); xSemaphoreGive( semaI2C ); /* give one semaphore */ /* imitialize i2c. */ Wire.begin( SDA_PIN, SCL_PIN ); // Wire.begin( SDA, SCL ); Wire.setClock( I2C_HERTZ ); // default = 100kbps /* bme280 start with i2c. */ Serial.print( "initialize BME280_01 " ); bme280_01.begin(); int bmeId = bme280_01.read( BME280_ID ); if( bmeId != BME280_ID_VALUE ) { Serial.print( "ID ERROR : " ); Serial.println( bmeId, HEX ); while(1) {} } Serial.print( "ID = 0x" ); Serial.println( bmeId, HEX ); Serial.print( "initialize BME280_02 " ); bme280_02.begin(); bmeId = bme280_02.read( BME280_ID ); if( bmeId != BME280_ID_VALUE ) { Serial.print( "ID ERROR : " ); Serial.println( bmeId, HEX ); //while(1) {} } Serial.print( "ID = 0x" ); Serial.println( bmeId, HEX ); /* connecting to ambient. */ Serial.print( "connecting to ambient." ); ambient.begin( ambientChannelId, ambientWriteKey, &client ); Serial.println( "...done." ); /* active i2c test task01. priority = 2 */ xTaskCreatePinnedToCore( i2cTestTask01, "", configMINIMAL_STACK_SIZE * 2, NULL, 2, &taskHandle[ TASK_ID_I2C_TEST01 ], 1 ); /* active i2c test task02. priority = 2 */ xTaskCreatePinnedToCore( i2cTestTask02, "", configMINIMAL_STACK_SIZE * 2, NULL, 2, &taskHandle[ TASK_ID_I2C_TEST02 ], 1 ); /* change the task priority to original. */ // vTaskPrioritySet( NULL, currentPriority ); // vTaskDelete( NULL ); /* delete loopTask. */ } /*************************************************************************/ /* loop. */ /*************************************************************************/ void loop() { time_t baseNTPRequestTime = passedTime; time_t baseStackMonitorTime = passedTime; time_t baseAmbientUpdateTime = passedTime; while( 1 ) { vTaskDelay( pdMS_TO_TICKS( 1 * 1000UL ) ); #if defined( __RUN_IN_STA_MODE__ ) /* get the time from ntp server. */ if( (passedTime - baseNTPRequestTime) >= 1 * 3600UL ) { baseNTPRequestTime = passedTime; connectNTP( ntpServer ); } #endif /* defined( __RUN_IN_STA_MODE__ ) */ /* stack monitor. */ if( (passedTime - baseStackMonitorTime) >= 10UL ) { baseStackMonitorTime = passedTime; stackMonitor(); } /* update data to ambient server. */ if( (passedTime - baseAmbientUpdateTime) >= 60UL ) { baseAmbientUpdateTime = passedTime; ambient.set(1, temperature01 ); // ambient.set(2, humidity01 ); // ambient.set(3, pressure01 ); // ambient.set(4, temperature02 ); // ambient.set(5, humidity02 ); // ambient.set(6, pressure02 ); // ambient.set(7, cpuCounter ); // if( ambient.send() == false ) Serial.println( "Transmitting to AMBIENT was error." ); if( ++cpuCounter >= 50 ) cpuCounter = 0; } } } /*************************************************************************/ /* stack monitor */ /*************************************************************************/ static void reportStackSize( TaskHandle_t taskHdl, int count ) { unsigned portBASE_TYPE stzckSize = uxTaskGetStackHighWaterMark( taskHdl ); String msg = " Task"; msg += String( count ); msg += " remains stack size = "; msg += String( stzckSize ); Serial.println( msg ); } static void stackMonitor() { int i; for( i = 0; i < sizeof(taskHandle) / sizeof(taskHandle[ 0 ]); i++ ) { reportStackSize( taskHandle[ i ], i ); } TaskHandle_t loopTaskHandle = xTaskGetCurrentTaskHandle(); reportStackSize( loopTaskHandle, i ); Serial.print( stringDataAndTime( NULL, NULL ) ); Serial.print( " ip : " ); Serial.println( myIpAddress ); } /*************************************************************************/ /* bme280Read */ /*************************************************************************/ static int bme280Read( bme280 *bm, BME280_S32_t *temperature, BME280_U32_t *pressure, BME280_U32_t *humidity ) { #define WAIT_FOR_SEMAPHORE_TIME (100UL) if( xSemaphoreTake( semaI2C, pdMS_TO_TICKS( WAIT_FOR_SEMAPHORE_TIME ) ) == pdFAIL ) return (-1); // not portMAX_DELAY bm->force( 1, 1 ); xSemaphoreGive( semaI2C ); /* give one semaphore */ vTaskDelay( pdMS_TO_TICKS( 2UL ) ); /**/ while( 1 ) { /* 変換が開始されるとbit3が1に、変換が終了してレジスタに書き込まれると、bit3が0になる */ if( xSemaphoreTake( semaI2C, pdMS_TO_TICKS( WAIT_FOR_SEMAPHORE_TIME ) ) == pdFAIL ) return (-1); // not portMAX_DELAY uint8_t status = bm->readStatus(); xSemaphoreGive( semaI2C ); /* give one semaphore */ if( status == 0xFF ) return (-1); if( status & 0x08 ) taskYIELD(); /* for Co-operative Scheduling */ else break; } taskYIELD(); /* for Co-operative Scheduling */ BME280_S32_t tempS32; if( xSemaphoreTake( semaI2C, pdMS_TO_TICKS( WAIT_FOR_SEMAPHORE_TIME ) ) == pdFAIL ) return (-1); // not portMAX_DELAY tempS32 = bm->readAdc_T(); xSemaphoreGive( semaI2C ); /* give one semaphore */ if( tempS32 == (-1) ) return (-1); taskYIELD(); /* for Co-operative Scheduling */ *temperature = (bm->BME280_compensate_T_int32( tempS32 ) + 5L) / 10L; if( xSemaphoreTake( semaI2C, pdMS_TO_TICKS( WAIT_FOR_SEMAPHORE_TIME ) ) == pdFAIL ) return (-1); // not portMAX_DELAY tempS32 = bm->readAdc_P(); xSemaphoreGive( semaI2C ); /* give one semaphore */ if( tempS32 == (-1) ) return (-1); taskYIELD(); /* for Co-operative Scheduling */ *pressure = (bm->BME280_compensate_P_int64( tempS32 ) + 128UL) / (256UL * 100UL); if( xSemaphoreTake( semaI2C, pdMS_TO_TICKS( WAIT_FOR_SEMAPHORE_TIME ) ) == pdFAIL ) return (-1); // not portMAX_DELAY tempS32 = bm->readAdc_H(); xSemaphoreGive( semaI2C ); /* give one semaphore */ if( tempS32 == (-1) ) return (-1); taskYIELD(); /* for Co-operative Scheduling */ *humidity = (bm->BME280_compensate_H_int32( tempS32 ) + 512UL) / 1024UL; return 0; } /*************************************************************************/ /* i2cTestTask01 */ /*************************************************************************/ void i2cTestTask01( void *execParam ) { Serial.println( "i2cTestTask01 start." ); while( 1 ) { vTaskDelay( pdMS_TO_TICKS( 1000UL ) ); /**/ BME280_S32_t temperature; BME280_U32_t pressure; BME280_U32_t humidity; if( bme280Read( &bme280_01, &temperature, &pressure, &humidity ) != 0 ) { Serial.println( "i2cTestTask01 does not take a semaphore." ); continue; } temperature01 = (int)((temperature + 5) / 10); pressure01 = (int)pressure; humidity01 = (int)humidity; Serial.print( "P01 = " ); Serial.print( pressure, DEC ); Serial.print( " H01 = " ); Serial.print( humidity, DEC ); Serial.print( " T01 = " ); Serial.print( temperature, DEC ); Serial.println(); } } /*************************************************************************/ /* i2cTestTask02 */ /*************************************************************************/ void i2cTestTask02( void *execParam ) { Serial.println( "i2cTestTask02 start." ); while( 1 ) { vTaskDelay( pdMS_TO_TICKS( 1000UL ) ); /**/ BME280_S32_t temperature; BME280_U32_t pressure; BME280_U32_t humidity; if( bme280Read( &bme280_02, &temperature, &pressure, &humidity ) != 0 ) { Serial.println( "i2cTestTask02 does not take a semaphore." ); continue; } temperature02 = (int)((temperature + 5) / 10); pressure02 = (int)pressure; humidity02 = (int)humidity; Serial.print( "P02 = " ); Serial.print( pressure, DEC ); Serial.print( " H02 = " ); Serial.print( humidity, DEC ); Serial.print( " T02 = " ); Serial.print( temperature, DEC ); Serial.println(); } } /*************************************************************************/ /* initialize GPIO */ /*************************************************************************/ static void initGPIO() { pinMode( ACT_LED_PIN, OUTPUT ); digitalWrite( ACT_LED_PIN, HIGH ); /**/ } /*************************************************************************/ /* ESP32 network parameter informatons. */ /*************************************************************************/ static void networkInformations() { Serial.println(); Serial.printf("Free Heap Size = %d\r\n", esp_get_free_heap_size()); Serial.printf("System Free Heap Size = %d\r\n", system_get_free_heap_size()); Serial.printf("Minimum Free Heap Size = %d\r\n", esp_get_minimum_free_heap_size()); Serial.println(); uint8_t mac[6]; esp_efuse_read_mac( mac ); Serial.printf("EFuse Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); system_efuse_read_mac( mac ); Serial.printf("System Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); esp_read_mac( mac, ESP_MAC_WIFI_STA ); Serial.printf("[Wi-Fi Station] Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); esp_read_mac( mac, ESP_MAC_WIFI_SOFTAP ); Serial.printf("[Wi-Fi SoftAP] Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); esp_read_mac( mac, ESP_MAC_BT ); Serial.printf("[Bluetooth] Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); esp_read_mac( mac, ESP_MAC_ETH ); Serial.printf("[Ethernet] Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); Serial.println(); } /*************************************************************************/ /* connect Wi-Fi */ /*************************************************************************/ static void connectWifi() { WiFi.disconnect(); #if defined( __RUN_IN_AP_MODE__ ) WiFi.mode( WIFI_AP ); WiFi.softAP( ssidAP, NULL, 6, 0, 4 ); // no pass, ch=6, ssid=broadcast, max connections=4 vTaskDelay( pdMS_TO_TICKS( 100UL ) ); WiFi.softAPConfig( apIP, apIP, subnet ); myIpAddress = WiFi.softAPIP(); Serial.print( "SSID : " ); Serial.print( ssidAP ); Serial.print( " AP IP address : " ); Serial.println( myIpAddress ); #else /* defined( __RUN_IN_AP_MODE__ ) */ unsigned long baseTim = millis(); WiFi.mode( WIFI_STA ); // WiFi.config( stationIP,dnsIP,gwIP,subnet ); /**/ WiFi.begin( ssidSTA, passSTA ); while( WiFi.status() != WL_CONNECTED ) { Serial.print( "." ); vTaskDelay( pdMS_TO_TICKS( 100UL ) ); } myIpAddress = WiFi.localIP(); Serial.print( "\r\nIP number assigned by DHCP is " ); Serial.print( myIpAddress ); Serial.print( " association time = " ); Serial.print( millis() - baseTim, DEC ); Serial.println( "ms" ); #endif /* defined( __RUN_IN_AP_MODE__ ) */ } /*************************************************************************/ /* connect ntp server. */ /*************************************************************************/ static void connectNTP( const char *server ) { #define TZ (9) /* init and get the time from ntp server. */ configTime( TZ * 3600UL, 0, server ); struct tm timeinfo; if( getLocalTime( &timeinfo ) == true ) { timerAlarmDisable( timer1second ); setUnixTime( &timeinfo ); timerAlarmEnable( timer1second ); } } /*************************************************************************/ /* set unixTime from date and time */ /*************************************************************************/ void setUnixTime( struct tm *tim ) { time_t presentTim = mktime( tim ); unixTime = presentTim; } /*************************************************************************/ /* get date and time string from unixTime */ /*************************************************************************/ String stringDataAndTime( char *yyyymmdd, char *hhmm ) { struct tm *tim = localtime( (time_t *)&unixTime ); char buffer[32]; sprintf( buffer, "%d/%02d/%02d %02d:%02d:%02d", tim->tm_year + 1900, tim->tm_mon + 1, tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec ); if( yyyymmdd != NULL ) { sprintf( yyyymmdd, "%04d%02d%02d", tim->tm_year + 1900, tim->tm_mon + 1, tim->tm_mday ); } if( hhmm != NULL ) { sprintf( hhmm, "%02d%02d", tim->tm_hour, tim->tm_min ); } return String( buffer ); } /*************************************************************************/ /* timer interrupt handler. */ /*************************************************************************/ void IRAM_ATTR onTimerEvery1seconds() { passedTime++; unixTime++; } /****************************************************************************/ /* Copyright (C) 2018- by hamayan */ /****************************************************************************/
bme280.cpp
/*********************************************************************************/ /* BME280を使用した温度と湿度と気圧の取得 */ /* designed by hamayan since 2015/09/29 */ /*********************************************************************************/ #include "bme280.h" /*************************************************************************/ /* 大域変数宣言 */ /*************************************************************************/ /*************************************************************************/ /* プロトタイプ宣言 */ /*************************************************************************/ /*************************************************************************/ /* 端子定義 */ /*************************************************************************/ /*************************************************************************/ /* インスタンス */ /*************************************************************************/ bme280::bme280( uint8_t adr ) { i2cAddress = adr; } void bme280::readCalibrationData() { uint8_t buf[26]; read( BME280_CALIB00, buf, 26 ); dig_T1 = ((uint16_t)(buf[1]) << 8) | ((uint16_t)(buf[0]) << 0); dig_T2 = ((signed short)(buf[3]) << 8) | ((signed short)(buf[2]) << 0); dig_T3 = ((signed short)(buf[5]) << 8) | ((signed short)(buf[4]) << 0); dig_P1 = ((uint16_t)(buf[7]) << 8) | ((uint16_t)(buf[6]) << 0); dig_P2 = ((signed short)(buf[9]) << 8) | ((signed short)(buf[8]) << 0); dig_P3 = ((signed short)(buf[11]) << 8) | ((signed short)(buf[10]) << 0); dig_P4 = ((signed short)(buf[13]) << 8) | ((signed short)(buf[12]) << 0); dig_P5 = ((signed short)(buf[15]) << 8) | ((signed short)(buf[14]) << 0); dig_P6 = ((signed short)(buf[17]) << 8) | ((signed short)(buf[16]) << 0); dig_P7 = ((signed short)(buf[19]) << 8) | ((signed short)(buf[18]) << 0); dig_P8 = ((signed short)(buf[21]) << 8) | ((signed short)(buf[20]) << 0); dig_P9 = ((signed short)(buf[23]) << 8) | ((signed short)(buf[21]) << 0); dig_H1 = buf[25]; read( BME280_CALIB26, buf, 7 ); dig_H2 = ((signed short)(buf[1]) << 8) | ((signed short)(buf[0]) << 0); dig_H3 = buf[2]; dig_H4 = ((signed short)(buf[3]) << 4) | ((signed short)(buf[4] & 0x0f) << 0); dig_H5 = ((signed short)(buf[4] & 0xf0) << 4) | ((signed short)(buf[5]) << 0); dig_H6 = (signed char)buf[6]; } BME280_S32_t bme280::readAdc_T() { uint8_t buf[3]; if( read( BME280_TEMP_MSB, buf, sizeof(buf) ) == (-1) ) { Serial.println( "bme280::readAdc_T read error 01." ); return (-1); } return ((BME280_S32_t)buf[0] << 12) | ((BME280_S32_t)buf[1] << 4) | ((BME280_S32_t)buf[2] >> 4); } BME280_S32_t bme280::readAdc_P() { uint8_t buf[3]; if( read( BME280_PRESS_MSB, buf, sizeof(buf) ) == (-1) ) { Serial.println( "bme280::readAdc_P read error 01." ); return (-1); } return ((BME280_S32_t)buf[0] << 12) | ((BME280_S32_t)buf[1] << 4) | ((BME280_S32_t)buf[2] >> 4); } BME280_S32_t bme280::readAdc_H() { uint8_t buf[2]; if( read( BME280_HUM_MSB, buf, sizeof(buf) ) == (-1) ) { Serial.println( "bme280::readAdc_H read error 01." ); return (-1); } return ((BME280_S32_t)buf[0] << 8) | ((BME280_S32_t)buf[1] << 0); } void bme280::readAdc_PTH( BME280_S32_t *p, BME280_S32_t *t, BME280_S32_t *h ) { uint8_t buf[8]; read( BME280_PRESS_MSB, buf, sizeof(buf) ); *h = ((BME280_S32_t)buf[0] << 8) | ((BME280_S32_t)buf[1] << 0); *t = ((BME280_S32_t)buf[2] << 12) | ((BME280_S32_t)buf[3] << 4) | ((BME280_S32_t)buf[4] >> 4); *p = ((BME280_S32_t)buf[5] << 12) | ((BME280_S32_t)buf[6] << 4) | ((BME280_S32_t)buf[7] >> 4); } void bme280::force( uint8_t pressureOverSample, uint8_t temperatureOverSample ) { write( BME280_CTRL_MEAS, ((pressureOverSample & 0x07) << 5) | ((temperatureOverSample & 0x07) << 2) | 1 ); } uint8_t bme280::readStatus() { uint8_t status = read( BME280_STATUS ); return status; } /*************************************************************************/ /* begin */ /*************************************************************************/ void bme280::begin() { write( BME280_RESET, BME280_RESET_VALUE ); /*RESET*/ delay( 1UL ); write( BME280_CTRL_MEAS, 0 ); /* set to sleep mode. */ write( BME280_CONFIG, (4 << 5) | (1 << 2) | 0 ); /*config:stand-by period =500ms,*/ /*iir filter=2 over samples,spi mode=ignore*/ write( BME280_CTRL_HUM, 1 ); /*ctrl hum*/ // write( BME280_CTRL_MEAS, (1 << 5) | (1 << 2) | 3 ); /*ctrl meas:temperature over sampling=1,*/ /*pressure over sampling=1,mode=normal*/ write( BME280_CTRL_MEAS, (1 << 5) | (1 << 2) | 0 ); /*ctrl meas:temperature over sampling=1,*/ /*pressure over sampling=1,mode=sleep*/ readCalibrationData(); } void bme280::begin( uint8_t meas, uint8_t hum, uint8_t config ) { write( BME280_RESET, BME280_RESET_VALUE ); /*RESET*/ delay( 1UL ); write( BME280_CTRL_MEAS, 0 ); /* set to sleep mode. */ write( BME280_CONFIG, config ); /*config*/ write( BME280_CTRL_MEAS, meas ); /*ctrl meas*/ write( BME280_CTRL_HUM, hum ); /*ctrl hum*/ readCalibrationData(); } /*************************************************************************/ /* I2C Write */ /*************************************************************************/ int bme280::write( uint8_t reg, uint8_t dat ) { Wire.beginTransmission( i2cAddress ); Wire.write( reg ); Wire.write( dat ); return Wire.endTransmission(); } /*************************************************************************/ /* I2C block Write */ /*************************************************************************/ int bme280::write( uint8_t reg, const uint8_t *dat, size_t len ) { Wire.beginTransmission( i2cAddress ); Wire.write( reg ); Wire.write( dat, len ); return Wire.endTransmission(); } /*************************************************************************/ /* byte data read */ /*************************************************************************/ int bme280::read( uint8_t reg ) { Wire.beginTransmission( i2cAddress ); Wire.write( reg ); Wire.endTransmission( false ); //endTransmission but keep the connection active Wire.requestFrom( (uint8_t)i2cAddress, (uint8_t)1 ); //Ask for bytes, once done, bus is released by default unsigned long baseTime = millis(); while( Wire.available() == 0 ) //Hang out until we get the # of bytes we expect { if( (millis() - baseTime) > WAIT_FOR_BME280_I2C_TIME ) return (-1); } return Wire.read() & 0x00ff; } /*************************************************************************/ /* any bytes data read */ /*************************************************************************/ int bme280::read( uint8_t reg, uint8_t data[], size_t len ) { Wire.beginTransmission( i2cAddress ); Wire.write( reg ); Wire.endTransmission( false ); //endTransmission but keep the connection active Wire.requestFrom( (uint8_t)i2cAddress, (uint8_t)len ); //Ask for bytes, once done, bus is released by default unsigned long baseTime = millis(); while( Wire.available() < len ) //Hang out until we get the # of bytes we expect { if( (millis() - baseTime) > WAIT_FOR_BME280_I2C_TIME ) return (-1); } for(int i = 0 ; i < len; i++) data[i] = Wire.read(); return 0; } #if 0 // Returns temperature in DegC, double precision. Output value of “51.23” equals 51.23 DegC. // t_fine carries fine temperature as global value BME280_S32_t t_fine; BME280_S32_t bme280::BME280_compensate_T_double(BME280_S32_t adc_T) { BME280_S32_t var1, var2, T; var1 = (((BME280_S32_t)adc_T)/16384.0 - ((BME280_S32_t)dig_T1)/1024.0) * ((BME280_S32_t)dig_T2); var2 = ((((BME280_S32_t)adc_T)/131072.0 - ((BME280_S32_t)dig_T1)/8192.0) * (((BME280_S32_t)adc_T)/131072.0 - ((BME280_S32_t)dig_T1)/8192.0)) * ((BME280_S32_t)dig_T3); t_fine = (BME280_S32_t)(var1 + var2); T = (var1 + var2) / 5120.0; return T; } // Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa BME280_S32_t bme280::BME280_compensate_P_double(BME280_S32_t adc_P) { BME280_S32_t var1, var2, p; var1 = ((BME280_S32_t)t_fine/2.0) - 64000.0; var2 = var1 * var1 * ((BME280_S32_t)dig_P6) / 32768.0; var2 = var2 + var1 * ((BME280_S32_t)dig_P5) * 2.0; var2 = (var2/4.0)+(((BME280_S32_t)dig_P4) * 65536.0); var1 = (((BME280_S32_t)dig_P3) * var1 * var1 / 524288.0 + ((BME280_S32_t)dig_P2) * var1) / 524288.0; var1 = (1.0 + var1 / 32768.0)*((BME280_S32_t)dig_P1); if (var1 == 0.0) { return 0; // avoid exception caused by division by zero } p = 1048576.0 - (BME280_S32_t)adc_P; p = (p - (var2 / 4096.0)) * 6250.0 / var1; var1 = ((BME280_S32_t)dig_P9) * p * p / 2147483648.0; var2 = p * ((BME280_S32_t)dig_P8) / 32768.0; p = p + (var1 + var2 + ((BME280_S32_t)dig_P7)) / 16.0; return p; } // Returns humidity in %rH as as double. Output value of “46.332” represents 46.332 %rH BME280_S32_t bme280::bme280_compensate_H_double(BME280_S32_t adc_H) { BME280_S32_t var_H; var_H = (((BME280_S32_t)t_fine) - 76800.0); var_H = (adc_H - (((BME280_S32_t)dig_H4) * 64.0 + ((BME280_S32_t)dig_H5) / 16384.0 * var_H)) * (((BME280_S32_t)dig_H2) / 65536.0 * (1.0 + ((BME280_S32_t)dig_H6) / 67108864.0 * var_H * (1.0 + ((BME280_S32_t)dig_H3) / 67108864.0 * var_H))); var_H = var_H * (1.0 - ((BME280_S32_t)dig_H1) * var_H / 524288.0); if (var_H > 100.0) var_H = 100.0; else if (var_H < 0.0) var_H = 0.0; return var_H; } #else // Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC. // t_fine carries fine temperature as global value BME280_S32_t t_fine; BME280_S32_t bme280::BME280_compensate_T_int32(BME280_S32_t adc_T) { BME280_S32_t var1, var2, T; var1 = ((((adc_T>>3) - ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11; var2 = (((((adc_T>>4) - ((BME280_S32_t)dig_T1)) * ((adc_T>>4) - ((BME280_S32_t)dig_T1))) >> 12) * ((BME280_S32_t)dig_T3)) >> 14; t_fine = var1 + var2; T = (t_fine * 5 + 128) >> 8; return T; } // Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits). // Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa BME280_U32_t bme280::BME280_compensate_P_int64(BME280_S32_t adc_P) { BME280_S64_t var1, var2, p; var1 = ((BME280_S64_t)t_fine) - 128000; var2 = var1 * var1 * (BME280_S64_t)dig_P6; var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17); var2 = var2 + (((BME280_S64_t)dig_P4)<<35); var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12); var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33; if (var1 == 0) { return 0; // avoid exception caused by division by zero } p = 1048576-adc_P; p = (((p<<31)-var2)*3125)/var1; var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25; var2 = (((BME280_S64_t)dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4); return (BME280_U32_t)p; } // Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits). // Output value of “47445” represents 47445/1024 = 46.333 %RH BME280_U32_t bme280::BME280_compensate_H_int32(BME280_S32_t adc_H) { BME280_S32_t v_x1_u32r; v_x1_u32r = (t_fine - ((BME280_S32_t)76800)); v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - (((BME280_S32_t)dig_H5) * v_x1_u32r)) + ((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r * ((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) * ((BME280_S32_t)dig_H2) + 8192) >> 14)); v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_H1)) >> 4)); v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); return (BME280_U32_t)(v_x1_u32r >> 12); } #endif /*********************************************************************************/ /* end of file */ /* designed by hamayan since 2015/09/29 */ /*********************************************************************************/
bme280.h
/****************************************************************************/ /* BME280 header */ /* Copyright (C) 2014 hamayan All Rights Reserved. */ /****************************************************************************/ #ifndef bme280_h #define bme280_h #include <Arduino.h> #include <Wire.h> extern "C" { } /* ESP32 Arduinoのドライバーがまともなら無限待ちでもいいかもしれないけれど、イマイチ信用できないのでタイムアウトを設定 */ #define WAIT_FOR_BME280_I2C_TIME (10UL) #define BME280_ID_VALUE 0x60 #define BME280_RESET_VALUE 0xB6 #define BME280_HUM_LSB 0xFE #define BME280_HUM_MSB 0xFD #define BME280_TEMP_XLSB 0xFC #define BME280_TEMP_LSB 0xFB #define BME280_TEMP_MSB 0xFA #define BME280_PRESS_XLSB 0xF9 #define BME280_PRESS_LSB 0xF8 #define BME280_PRESS_MSB 0xF7 #define BME280_CONFIG 0xF5 #define BME280_CTRL_MEAS 0xF4 #define BME280_STATUS 0xF3 #define BME280_CTRL_HUM 0xF2 #define BME280_CALIB26 (0xE1 + 0) #define BME280_CALIB27 (0xE1 + 1) #define BME280_CALIB28 (0xE1 + 2) #define BME280_CALIB29 (0xE1 + 3) #define BME280_CALIB30 (0xE1 + 4) #define BME280_CALIB31 (0xE1 + 5) #define BME280_CALIB32 (0xE1 + 6) #define BME280_CALIB33 (0xE1 + 7) #define BME280_CALIB34 (0xE1 + 8) #define BME280_CALIB35 (0xE1 + 9) #define BME280_CALIB36 (0xE1 + 10) #define BME280_CALIB37 (0xE1 + 11) #define BME280_CALIB38 (0xE1 + 12) #define BME280_CALIB39 (0xE1 + 13) #define BME280_CALIB40 (0xE1 + 14) #define BME280_CALIB41 (0xE1 + 15) #define BME280_RESET 0xE0 #define BME280_ID 0xD0 #define BME280_CALIB00 (0x88 + 0) #define BME280_CALIB01 (0x88 + 1) #define BME280_CALIB02 (0x88 + 2) #define BME280_CALIB03 (0x88 + 3) #define BME280_CALIB04 (0x88 + 4) #define BME280_CALIB05 (0x88 + 5) #define BME280_CALIB06 (0x88 + 6) #define BME280_CALIB07 (0x88 + 7) #define BME280_CALIB08 (0x88 + 8) #define BME280_CALIB09 (0x88 + 9) #define BME280_CALIB10 (0x88 + 10) #define BME280_CALIB11 (0x88 + 11) #define BME280_CALIB12 (0x88 + 12) #define BME280_CALIB13 (0x88 + 13) #define BME280_CALIB14 (0x88 + 14) #define BME280_CALIB15 (0x88 + 15) #define BME280_CALIB16 (0x88 + 16) #define BME280_CALIB17 (0x88 + 17) #define BME280_CALIB18 (0x88 + 18) #define BME280_CALIB19 (0x88 + 19) #define BME280_CALIB20 (0x88 + 20) #define BME280_CALIB21 (0x88 + 21) #define BME280_CALIB22 (0x88 + 22) #define BME280_CALIB23 (0x88 + 23) #define BME280_CALIB24 (0x88 + 24) #define BME280_CALIB25 (0x88 + 25) #if 0 typedef double BME280_S32_t; #else typedef signed long BME280_S32_t; #endif typedef unsigned long BME280_U32_t; typedef signed long long BME280_S64_t; class bme280 { private: uint8_t i2cAddress; uint16_t dig_T1; signed short dig_T2,dig_T3; uint16_t dig_P1; signed short dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9; uint8_t dig_H1; signed short dig_H2; uint8_t dig_H3; signed short dig_H4,dig_H5; signed char dig_H6; void readCalibrationData(); public: bme280( uint8_t adr ); void begin(); void begin( uint8_t meas, uint8_t hum, uint8_t config ); int write( uint8_t reg, uint8_t dat ); int write( uint8_t addr, const uint8_t *dat, unsigned int len ); int read( uint8_t reg ); int read( uint8_t reg, uint8_t data[], size_t len ); BME280_S32_t readAdc_T(); BME280_S32_t readAdc_P(); BME280_S32_t readAdc_H(); void readAdc_PTH( BME280_S32_t *p, BME280_S32_t *t, BME280_S32_t *h ); void force( uint8_t pressureOverSample, uint8_t temperatureOverSample ); uint8_t readStatus(); #if 0 BME280_S32_t BME280_compensate_T_double(BME280_S32_t adc_T); BME280_S32_t BME280_compensate_P_double(BME280_S32_t adc_P); BME280_S32_t bme280_compensate_H_double(BME280_S32_t adc_H); #else BME280_S32_t BME280_compensate_T_int32(BME280_S32_t adc_T); BME280_U32_t BME280_compensate_P_int64(BME280_S32_t adc_P); BME280_U32_t BME280_compensate_H_int32(BME280_S32_t adc_H); #endif }; #endif /*bme280_H*/ /****************************************************************************/ /* Copyright (C) 2014 hamayan All Rights Reserved. */ /****************************************************************************/
※実は自分で排他制御を用意する必要が無かった???次号でI2Cの排他制御に突っ込んでみる!
※I2Cを共有するのは同一優先度のタスク間なので、ここは排他制御で一番お手軽なバイナリーセマフォを使用。優先度が同一または隣接まではバイナリーセマフォで充分だと思うが、2つ以上優先度が離れている場合はミューテックスとか別の手段も検討する必要があります。
と言う訳で、githubから最新版を落としてインストールしてください。
ESP32、、、参考になる日本語の読み物、ないよね~
大きな配列を取ると怒られるぅ~~~ [ESP32]
またもやM5Stackである。
uint16_t bitMap[ (80 * 3 * 60 * 3) ];
こんな風に配列を取ると、リンカーに「オーバーフローだクソ野郎」って怒られるようになってしまった。
、、、region `dram0_0_seg' overflowed by 2744 bytes、、、
色々試すと、配列のサイズが40000を超えたあたりでエラーになっている。人によって違うだろうけれど。
リンカースクリプトのdram0_0_segのサイズ設定がしょぼいからだろうけれど、どこを直すと良いのか判らん。
とりあえずHEAP領域から確保すれば怒られない。まだ動かしていないけれど。
uint16_t *bitMap;
bitMap = new uint16_t[ 80 * 3 * 60 * 3 ];
大きな配列を取れないのは、320×240ピクセルで16bitカラーのLCDを持つ装置としては、「どうなんだそれ?」って感じだが。
無理矢理「解決」にされていて、草!
https://www.esp32.com/viewtopic.php?t=1831
どうでもイイが、Arduinoの環境設定のボードマネージャーに、
http://www.M5Stack.com/download/package_m5stack_index.json
は、もう書かなくてもイイらしい。どうせ書いても変なファイルを引っ張ってくるだけだし。
uint16_t bitMap[ (80 * 3 * 60 * 3) ];
こんな風に配列を取ると、リンカーに「オーバーフローだクソ野郎」って怒られるようになってしまった。
、、、region `dram0_0_seg' overflowed by 2744 bytes、、、
色々試すと、配列のサイズが40000を超えたあたりでエラーになっている。人によって違うだろうけれど。
リンカースクリプトのdram0_0_segのサイズ設定がしょぼいからだろうけれど、どこを直すと良いのか判らん。
とりあえずHEAP領域から確保すれば怒られない。まだ動かしていないけれど。
uint16_t *bitMap;
bitMap = new uint16_t[ 80 * 3 * 60 * 3 ];
大きな配列を取れないのは、320×240ピクセルで16bitカラーのLCDを持つ装置としては、「どうなんだそれ?」って感じだが。
無理矢理「解決」にされていて、草!
https://www.esp32.com/viewtopic.php?t=1831
どうでもイイが、Arduinoの環境設定のボードマネージャーに、
http://www.M5Stack.com/download/package_m5stack_index.json
は、もう書かなくてもイイらしい。どうせ書いても変なファイルを引っ張ってくるだけだし。
部品を実装してみただけ [ESP32]
ESP32 for arduino のライブラリの更新と、AquesTalk-ESP、、、 [ESP32]
また更新かよ!2018年7月11日
ESP32 Arduinoライブラリ更新作業メモ
ESP32 for Arduinoのライブラリが新しくなっている事に気付いたので、更新をしたいのだが、GitHubからzipファイルをダウンロードして、まるっとコピーしてしまうと、AquesTalk-ESP関連の変更がいろいろ無効になってしまう。
面倒だなぁ、、、
やっている事は、
1.¥tools¥sdk¥libにlibaquestalk.aを追加
2.¥tools¥sdk¥include¥aquestalkにaquestalk.hを追加
3.esp32の下にplatform.local.txtを作成し、中身は以下とする
以上
1.AquesTalk関連ファイルを保存しておいて、、、
2.旧ライブラリファイル群をフォルダーから削除し、、、
3.新ライブラリファイル群を削除したフォルダーにコピーし、、、
4.toolsのget.exeを行い、、、
5.AquesTalk関連ファイルを差し戻す。
参照
https://github.com/espressif/arduino-esp32
http://blog-yama.a-quest.com/?eid=970188
ちゃんと動くかどうかは、まだ確認していない。
と思ったら、、、なんかインクルードファイルの検索パスが変わっていないかぁ、、、
従来
#include <FreeRTOS.h>
で良かったものがエラーになって、以下の様にしないとコンパイルできない、、、
#include <freertos\FreeRTOS.h>
くそぅ、、、
EEPROM.cppの180行目辺りからこんな代入しているから、
コンパイラにすっごく怒られているんだけれど、、、しょうがないので初期値を与えてエラー回避。
今回の更新で、WiFi.configがまともに動くようになったのは良かった。
ESP32 Arduinoライブラリ更新作業メモ
ESP32 for Arduinoのライブラリが新しくなっている事に気付いたので、更新をしたいのだが、GitHubからzipファイルをダウンロードして、まるっとコピーしてしまうと、AquesTalk-ESP関連の変更がいろいろ無効になってしまう。
面倒だなぁ、、、
やっている事は、
1.¥tools¥sdk¥libにlibaquestalk.aを追加
2.¥tools¥sdk¥include¥aquestalkにaquestalk.hを追加
3.esp32の下にplatform.local.txtを作成し、中身は以下とする
compiler.c.extra_flags="-I{compiler.sdk.path}/include/aquestalk" compiler.cpp.extra_flags="-I{compiler.sdk.path}/include/aquestalk" compiler.c.elf.libs=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lhal -lnewlib -ldriver -lbootloader_support -lpp -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -lmdns -lvfs -lsoc -lcore -lsdmmc -lcoap -ltcpip_adapter -lc_nano -lrtc -lspi_flash -lwpa2 -lesp32 -lapp_update -lnghttp -lspiffs -lespnow -lnvs_flash -lesp_adc_cal -llog -lexpat -lm -lc -lheap -lmbedtls -llwip -lnet80211 -lpthread -ljson -lstdc++ -laquestalk
以上
1.AquesTalk関連ファイルを保存しておいて、、、
2.旧ライブラリファイル群をフォルダーから削除し、、、
3.新ライブラリファイル群を削除したフォルダーにコピーし、、、
4.toolsのget.exeを行い、、、
5.AquesTalk関連ファイルを差し戻す。
参照
https://github.com/espressif/arduino-esp32
http://blog-yama.a-quest.com/?eid=970188
ちゃんと動くかどうかは、まだ確認していない。
と思ったら、、、なんかインクルードファイルの検索パスが変わっていないかぁ、、、
従来
#include <FreeRTOS.h>
で良かったものがエラーになって、以下の様にしないとコンパイルできない、、、
#include <freertos\FreeRTOS.h>
くそぅ、、、
EEPROM.cppの180行目辺りからこんな代入しているから、
uint8_t value; return EEPROMClass::readAll (address, value);
コンパイラにすっごく怒られているんだけれど、、、しょうがないので初期値を与えてエラー回避。
今回の更新で、WiFi.configがまともに動くようになったのは良かった。
ESP32 for arduino のmain.cppの変更? [ESP32]
main.cppのloopTaskの中から、micros()が削除されたね。
Use esp_timer_get_time as time source for micros and mills
だそうだ。
従来micro秒の更新は、loopTaskの中のmicros()で行っていたので、loopTaskに処理が回らないと更新がままならなかったが、それは解消したと言う事かなぁ。
Use esp_timer_get_time as time source for micros and mills
だそうだ。
従来micro秒の更新は、loopTaskの中のmicros()で行っていたので、loopTaskに処理が回らないと更新がままならなかったが、それは解消したと言う事かなぁ。