Le Queue, code, di FreeRTOs sono metodi per scambiare dati tra due task. In questo esempio una coda monodirezionale (un task invia dati e l'altro li riceve)
-----------------------------------------------------------------
#include <Arduino_FreeRTOS.h>
#include <queue.h>
QueueHandle_t coda;
int codasize = 10;
void sender( void *pvParameters );
void receiver( void *pvParameters );
void setup() {
Serial.begin(9600);
coda = xQueueCreate(codasize,sizeof(int));
if ( coda == NULL ) {
Serial.println("Errore nella creazione");
}
xTaskCreate(sender,(const portCHAR *)"Sender",128,NULL,3,NULL);
xTaskCreate(receiver,(const portCHAR *)"Receiver",128,NULL,2,NULL);
}
void loop()
{
}
void sender( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
for (;;)
{
for (int t=0;t<5;t++){
xQueueSend(coda,&t,portMAX_DELAY);
}
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}
void receiver( void *pvParameters __attribute__((unused)) )
{
int elemento;
for (;;)
{
for (int t=0;t<codasize;t++){
xQueueReceive(coda,&elemento,portMAX_DELAY);
Serial.print(elemento);
Serial.print("|");
}
Serial.println();
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}
martedì 5 marzo 2019
Semafori binari in FreeRTOS con Arduino
I semafori binari (o Mutex) sono metodi per stabilire per un task per capire se una risorsa condivisa e' occupata da un altro task (e quindi non utilizzabile) oppure e' disponibile
In questo esempio sono creati due task che ogni 5 secondi si sovrappongono e cercano entrambi di scrivere sulla porta seriale.
----------------------------------------------------------------------------------
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
SemaphoreHandle_t semaforo;
void blink_even( void *pvParameters );
void blink_odd( void *pvParameters );
void setup() {
Serial.begin(9600);
if ( semaforo == NULL ) {
semaforo = xSemaphoreCreateMutex();
if ((semaforo) != NULL)
xSemaphoreGive((semaforo));
}
// crea i due task
xTaskCreate(blink_even,(const portCHAR *)"BlinkEven",128,NULL,3,NULL);
xTaskCreate(blink_odd,(const portCHAR *)"BlinkOdd",128,NULL,2,NULL);
}
void loop()
{
}
void blink_even( void *pvParameters __attribute__((unused)) )
{
for (;;)
{// qui viene testato se il semaforo e' settato, se la risorsa e'occupata riprova per 5 tick ..in caso la risorsa
// rimanga occupata abbandona
if (xSemaphoreTake(semaforo, ( TickType_t ) 5 ) == pdTRUE )
{
Serial.println("Even");
xSemaphoreGive(semaforo);
}
vTaskDelay( 5000 / portTICK_PERIOD_MS );
}
}
void blink_odd( void *pvParameters __attribute__((unused)) )
{
for (;;)
{
if (xSemaphoreTake(semaforo, ( TickType_t ) 5 ) == pdTRUE )
{
Serial.println("Odd");
xSemaphoreGive(semaforo);
}
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}
In questo esempio sono creati due task che ogni 5 secondi si sovrappongono e cercano entrambi di scrivere sulla porta seriale.
----------------------------------------------------------------------------------
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
SemaphoreHandle_t semaforo;
void blink_even( void *pvParameters );
void blink_odd( void *pvParameters );
void setup() {
Serial.begin(9600);
if ( semaforo == NULL ) {
semaforo = xSemaphoreCreateMutex();
if ((semaforo) != NULL)
xSemaphoreGive((semaforo));
}
// crea i due task
xTaskCreate(blink_even,(const portCHAR *)"BlinkEven",128,NULL,3,NULL);
xTaskCreate(blink_odd,(const portCHAR *)"BlinkOdd",128,NULL,2,NULL);
}
void loop()
{
}
void blink_even( void *pvParameters __attribute__((unused)) )
{
for (;;)
{// qui viene testato se il semaforo e' settato, se la risorsa e'occupata riprova per 5 tick ..in caso la risorsa
// rimanga occupata abbandona
if (xSemaphoreTake(semaforo, ( TickType_t ) 5 ) == pdTRUE )
{
Serial.println("Even");
xSemaphoreGive(semaforo);
}
vTaskDelay( 5000 / portTICK_PERIOD_MS );
}
}
void blink_odd( void *pvParameters __attribute__((unused)) )
{
for (;;)
{
if (xSemaphoreTake(semaforo, ( TickType_t ) 5 ) == pdTRUE )
{
Serial.println("Odd");
xSemaphoreGive(semaforo);
}
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}
Diventare amministratore della macchinetta del caffe'
Per motivi non meglio spiegati (sarebbe interessante scoprire il metodo) la macchinetta del caffe' dell'ufficio e' andata in crisi lasciando aperta una bella shell di amministrazione ...ops menu' di configurazione con cui poter fare qualunque cosa
Per interagire con il menu si possono usare Zucchero - e Zucchero + per andare indietro ed avanti, Caffe' e cioccolato per selezionare (Ok) e Caffe' al gingseng per andare indietro nel menu (i pusalnti sono illuminati in modalita' di amministrazione)
Si puo' fare di tutto, dal cambiare il prezzo delle varie bevande ad avere le statistiche. Peraltro sembra che la macchinetta possa trasmettere i dati in remoto (non credo invece che possa essere controllata in remoto altrimenti sarebbe gia' stata resettata)
.....e no, non ne ho approfittato..nemmeno un caffe'
Per interagire con il menu si possono usare Zucchero - e Zucchero + per andare indietro ed avanti, Caffe' e cioccolato per selezionare (Ok) e Caffe' al gingseng per andare indietro nel menu (i pusalnti sono illuminati in modalita' di amministrazione)
Si puo' fare di tutto, dal cambiare il prezzo delle varie bevande ad avere le statistiche. Peraltro sembra che la macchinetta possa trasmettere i dati in remoto (non credo invece che possa essere controllata in remoto altrimenti sarebbe gia' stata resettata)
.....e no, non ne ho approfittato..nemmeno un caffe'
lunedì 4 marzo 2019
Mongoose OS ed ESP-Wroom-32
Un paio di indicazioni:
1) Mongoose OS non e' legato a MongoDB e Node.JS...maledetta fantasia nel mettere i nomi
2) in estrema sintesi Mongoose OS e' molto simile al cloud di Particle con la differenza che quest'ultimo e' legato a doppio filo con l'hardware di Particle (Electron, Photon) mentre Mongoose OS puo' essere usato con hardware ESP32 ed STM32
Per inziare ho scaricato il pacchetto generico per Linux
curl -fsSL https://mongoose-os.com/downloads/mos/install.sh | /bin/bash mos
mos clone https://github.com/mongoose-os-apps/demo-js app1
mos wifi WIFI_NETWORK_NAME WIFI_PASSWORD
Una volta ottenuta la connessione si rete si puo' impostare la connessione al cloud.Ci si collega a https://dash.mongoose-os.com/ e si crea un nuovo dispositivo (con il profilo gratuito se ne possono creare fino a 3)
mos config-set dash.enable=true dash.token=xxxxxxxxdc08
1) Mongoose OS non e' legato a MongoDB e Node.JS...maledetta fantasia nel mettere i nomi
2) in estrema sintesi Mongoose OS e' molto simile al cloud di Particle con la differenza che quest'ultimo e' legato a doppio filo con l'hardware di Particle (Electron, Photon) mentre Mongoose OS puo' essere usato con hardware ESP32 ed STM32
Per inziare ho scaricato il pacchetto generico per Linux
curl -fsSL https://mongoose-os.com/downloads/mos/install.sh | /bin/bash mos
e si lancia il programma in $HOME/.mos/bin/mos
si aprira' il browser di default all'indirizzo http://127.0.0.1:1992/
Le istruzioni dicono di premere CTRL+N per creare una nuova app ma su Chrome per Linux questa combinazione apre una nuova scheda del browser. Si puo' pero' usare la barra in basso allo schermo (vicino all'icona arancione che si trova nell'angolo in basso a destra) per digitare
a seguire (la compilazione avviente completamente sul cloud...i risultati saranno nella sottodirectory build)
mos build
mos flash
Per avere la possibilita' di interagire in remoto ed effettuare anche degli OTA update (Over the air) si puo' configurare la connessione con l'access point con
si copia il token (basta andare sopra al token) e da http://127.0.0.1:1992/ si digita
se tutto e' andato bene il dispositivo comparira' on line nel cloud
Dall'interfaccia Web si puo' impostare il comando remoto tramite Mobile (si tratta di un link)
Si puo' accendere o spengere una porta digitale. Con il modulo ESP-Wroom-32 il pin preimpostato e' il numero 13 (IO13 a destra di GND)
La programmazione successiva puo' avvenire mediante C o Javascript. In generale, leggendo anche il forum, si tratta di un progetto piuttosto immaturo con un supporto ancora scarso con l'hardware (nonostante sia comunque presente la possibilita' di convertire le librerie Arduino nei progetti Mongoose)
Dall'interfaccia Web si puo' impostare il comando remoto tramite Mobile (si tratta di un link)
Si puo' accendere o spengere una porta digitale. Con il modulo ESP-Wroom-32 il pin preimpostato e' il numero 13 (IO13 a destra di GND)
La programmazione successiva puo' avvenire mediante C o Javascript. In generale, leggendo anche il forum, si tratta di un progetto piuttosto immaturo con un supporto ancora scarso con l'hardware (nonostante sia comunque presente la possibilita' di convertire le librerie Arduino nei progetti Mongoose)
venerdì 1 marzo 2019
Impostazione ProtonVPN su Debian 9
Questo e' un promemoria perche' regolarmente mi scordo come si fa ad impostare ProtonVPN su Debian
per prima si installano i pacchetti per openvpn in Network Manager
apt-get install openvpn network-manager-openvpn network-manager-openvpn-gnome
per prima si installano i pacchetti per openvpn in Network Manager
apt-get install openvpn network-manager-openvpn network-manager-openvpn-gnome
Si logga quindi su https://account.protonvpn.com/login/
Da Account si copia OpenVPN/IKEv2 Username
e da Download si scaricano i file .ovpn relativi ai server (free nel mio caso)
Fatto cio' si apre Network Manager/VPN/VPN Settings e si aggiunge il nuovo server importando il file .ovpn ed inserendo come username il precedente OpenVPN/IKEv2 Username e la password
Toolchain per ESP32 su Linux
Post per impostare l'ambiente di sviluppo esp32-idf su Debian 9
si installano i pacchetti
apt-get install gcc git wget make libncurses-dev flex bison gperf python python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing
e successivamente
mkdir esp
cd ~/esp
si scarica il compilatore e lo si decomprime
si installano i pacchetti
apt-get install gcc git wget make libncurses-dev flex bison gperf python python-pip python-setuptools python-serial python-cryptography python-future python-pyparsing
e successivamente
mkdir esp
cd ~/esp
git clone -b v3.1.3 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
export IDF_PATH=~/esp/esp-idf
export IDF_PATH=~/esp/esp-idf
tar -xzf ~/Downloads/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
si inserisce l'ambiente di sviluppo in Path
export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
si inserisce l'ambiente di sviluppo in Path
export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
se tutto e' andato bene si puo' andare in $HOME/esp/esp-idf/examples/get-started/hello_world e digitare make per vedere se il progetto si compila (viene generato il bootloader all'indirizzo 0x10000 oltre al programma vero e proprio all'inidirizzo 0x8000). Al termine si puo' digitare
make flash
per copiarlo sulla scheda (questi i messaggi)
-----------------------------------------
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000 )...
esptool.py v2.6
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32D0WDQ6 (revision 0)
Features: WiFi, BT, Dual Core, Coding Scheme None
MAC: 24:0a:c4:05:df:5c
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 21184 bytes to 12506...
Wrote 21184 bytes (12506 compressed) at 0x00001000 in 1.1 seconds (effective 153.7 kbit/s)...
Hash of data verified.
Compressed 144080 bytes to 68379...
Wrote 144080 bytes (68379 compressed) at 0x00010000 in 6.0 seconds (effective 190.8 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 1843.8 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
---------------------------------------------------
Collegandosi con minicom alla /dev/ttyUSB0 si ottengono le seguenti stringhe
---------------------------------------------------
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5804
load:0x40078000,len:9188
load:0x40080000,len:6084
entry 0x4008032c
I (29) boot: ESP-IDF v3.1.3 2nd stage bootloader
I (29) boot: compile time 11:25:47
I (29) boot: Enabling RNG early entropy source...
I (34) boot: SPI Speed : 40MHz
I (38) boot: SPI Mode : DIO
I (42) boot: SPI Flash Size : 4MB
I (46) boot: Partition Table:
I (49) boot: ## Label Usage Type ST Offset Length
I (57) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (64) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (72) boot: 2 factory factory app 00 00 00010000 00100000
I (79) boot: End of partition table
I (83) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x07180 ( 2p
I (102) esp_image: segment 1: paddr=0x000171a8 vaddr=0x3ffb0000 size=0x022a0 ( d
I (106) esp_image: segment 2: paddr=0x00019450 vaddr=0x40080000 size=0x00400 ( d
I (110) esp_image: segment 3: paddr=0x00019858 vaddr=0x40080400 size=0x067b8 ( d
I (130) esp_image: segment 4: paddr=0x00020018 vaddr=0x400d0018 size=0x11150 ( p
I (155) esp_image: segment 5: paddr=0x00031170 vaddr=0x40086bb8 size=0x02130 ( d
I (164) boot: Loaded app from partition at offset 0x10000
I (164) boot: Disabling RNG early entropy source...
I (166) cpu_start: Pro cpu up.
I (170) cpu_start: Starting app cpu, entry point is 0x40080e74
I (162) cpu_start: App cpu up.
I (181) heap_init: Initializing. RAM available for dynamic allocation:
I (187) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (193) heap_init: At 3FFB32F8 len 0002CD08 (179 KiB): DRAM
I (200) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (206) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (213) heap_init: At 40088CE8 len 00017318 (92 KiB): IRAM
I (219) cpu_start: Pro cpu start user code
I (237) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Hello world!
This is ESP32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 0, 4MB exterh
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...
Restarting in 2 seconds...
Restarting in 1 seconds...
Restarting in 0 seconds...
Restarting now.
-------------------------------------------------------
Questo comportamento e' coerente con il programma hello_world.c
---------------------------------------------
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
void app_main()
{
printf("Hello world!\n");
/* Print chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ",
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
printf("silicon revision %d, ", chip_info.revision);
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
for (int i = 10; i >= 0; i--) {
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}
------------------------------------------------------
In conclusione l'ambiente di sviluppo e' funzionante
Calcolo durata batteria per mini progetti
Fino ad oggi calcolavo la durata teorica di funzionamento di un utilizzatore (tipicamente una Arduino) connesso ad una batteria LiPo dividendo i mAh della batteria per il consumo in ampere dell'utilizzatore
Per esempio: con una batteria da 2500 mAh ed una Arduino Uno in configurazione base con consumo da 45 mA stimavo il tempo di funzionamento in 2500 mAh/45 mA cioe' circa 55 ora
In realta' il calcolo e' sbagliato perche' si deve tenere conto della potenza in Watt (o meglio si deve tenere in conto della potenza nel caso in cui il voltaggio della batteria e dell'utilizzatore sono identici ....ma questo e' un caso particolare)
Prendendo l'esempio precedente una batteria LiPo da 2500 mAh con un 3.7 ha un potenza di 9.25 Wh, La Arduino Uno ha un consumo di circa 45mA a 5 V pèari a 0.225 W. Dividendo 9.25 Wh per 0.225 h si ottiene che il tempo di funzionamento di circa 41 ore (valore sensibilmente differente dal calcolo, errato, precedente)
Per esempio: con una batteria da 2500 mAh ed una Arduino Uno in configurazione base con consumo da 45 mA stimavo il tempo di funzionamento in 2500 mAh/45 mA cioe' circa 55 ora
In realta' il calcolo e' sbagliato perche' si deve tenere conto della potenza in Watt (o meglio si deve tenere in conto della potenza nel caso in cui il voltaggio della batteria e dell'utilizzatore sono identici ....ma questo e' un caso particolare)
Prendendo l'esempio precedente una batteria LiPo da 2500 mAh con un 3.7 ha un potenza di 9.25 Wh, La Arduino Uno ha un consumo di circa 45mA a 5 V pèari a 0.225 W. Dividendo 9.25 Wh per 0.225 h si ottiene che il tempo di funzionamento di circa 41 ore (valore sensibilmente differente dal calcolo, errato, precedente)
Iscriviti a:
Post (Atom)
Debugger integrato ESP32S3
Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede nell'ID USB della porta Jtag. Nel modulo...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...