Visualizzazione post con etichetta Arduino. Mostra tutti i post
Visualizzazione post con etichetta Arduino. Mostra tutti i post

mercoledì 26 giugno 2024

Primo spettro di riflettanza con SparkFun Triad Spectroscopy Sensor - AS7265x

 Lo spettro di riflettanza e' stato ottenuto dividendo il valore calibrato della foglia per il valore calibrato nel corrispondente canale dello spectralon

 


 


spettro spectralon foglia
410 0.104046939572376 7631.94 794.08
435 0.100663330010594 1916.09 192.88
460 0.0941060471276098 5496.99 517.3
485 0.0846332588803228 2220.64 187.94
510 0.127077186925102 2647.21 336.4
535 0.209306506039295 3170.9 663.69
560 0.204982889816192 1385.14 283.93
585 0.171727663387711 1473.03 252.96
610 0.0880803424432005 4555.5 401.25
645 0.121946929339632 795.92 97.06
680 0.123669783940664 1054.34 130.39
705 0.278338126099833 232.99 64.85
730 0.766924924721724 295.57 226.68
760 0.718044428259286 219.68 157.74
810 0.575862515972518 539.99 310.96
860 1.02470169644788 2543.55 2606.38
900 0.777308820373417 139.79 108.66
940 0.344453330286759 87.53 30.15


Primi passi con SparkFun Triad Spectroscopy Sensor - AS7265x

 Primi approcci per vedere se il sensore multispettrale e' affidabile per l'uso multispettrale 

In questo prova e' stata verificata la ripetibilita' nel tempo delle misure ponendo il sensore su uno spectralon ed effettuando 350 misure di bianco (il supporto del sensore e' stato ripreso da qui https://github.com/Scottapotamas/AS7265x-triad-ui/tree/master/mechanical)

 



 

Lo script per la misura ha previsto il massimo tempo di integrazione (con valori bassi in IR praticamente non c'era segnale)


sensor.setGain(AS7265X_GAIN_16X);
sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_ONE_SHOT);

sensor.setIntegrationCycles(255);


L'errore per ogni canale e' stato stimato prendendo la standard deviation e dividendo per la media


A 0.44%
B 0.49%
C 0.25%
D 0.34%
E 0.05%
F 0.05%
G 0.07%
H 0.07%
R 0.10%
I 0.07%
S 0.09%
J 0.08%
T 0.13%
U 0.00%
V 0.37%
W 0.74%
K 1.55%
L 0.56%


Come si deve l'errore e' piuttosto vario tra i vari canali

 

Plottando la misura di ogni canale nel tempo si osserva una chiara deriva per ogni canale con in alcuni casi l'accenno di un valore asintotivo mentre in altri no 


 

 



 

 










La Dark Current e' stabile (prova su 450 misure)



A B C D E F G H R I S J T U V W K L
St Dev 0.00 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.00 0.46 0.00 0.40 0.40 0.27 0.00 0.00 0.00
Media 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.41 1.02 0.00 0.80 0.83 0.84 1.08 0.64 0.00

martedì 7 maggio 2024

ESP32-2432S028R e LVGL

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 riferimento e' il seguente https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display (oppure https://github.com/hexeguitar/ESP32_TFT_PIO)

Esempio di TFT_eSPI

Per gli schemi elettrici di tutta la famiglia di dispositivi si cerchi https://github.com/rzeldent/platformio-espressif32-sunton in assets





Si puo' usare tramite Arduino Ide importando le due librerie TFT_eSPI and XPT2046_Touchscreen

Iniziando dallo schermo TFT prima di provare gli esempi della libreria si deve modificare il file User_Setup.h nel folder in Arduino/libraries/TFT_eSPI

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

 //USER DEFINED SETTINGS
#define ILI9341_2_DRIVER    
#define TFT_WIDTH  240
#define TFT_HEIGHT 320
#define TFT_BL   21           
#define TFT_BACKLIGHT_ON HIGH  
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15  
#define TFT_DC   2  
#define TFT_RST  12  
#define TFT_BL   21
#define TOUCH_CS 33  
#define LOAD_GLCD   
#define LOAD_FONT2  
#define LOAD_FONT4  
#define LOAD_FONT6  
#define LOAD_FONT7  
#define LOAD_FONT8  
#define LOAD_GFXFF  
#define SMOOTH_FONT
#define SPI_FREQUENCY  55000000
#define SPI_READ_FREQUENCY  20000000
//Touch Screen: ?????????ß
#define XPT2046_IRQ 36
#define XPT2046_MOSI 32
#define XPT2046_MISO 39
#define XPT2046_CLK 25
#define XPT2046_CS 33
#define SPI_TOUCH_FREQUENCY  2500000

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

 

Per provare la sola componente TouchScreen  si puo' usare il seguente esempio (quello di default non funziona perche' non sono mappati in modo corretto i pin)

#include <SPI.h>
#include <XPT2046_Touchscreen.h>

#define XPT2046_IRQ 36 // T_IRQ
#define XPT2046_MOSI 32 // T_DIN
#define XPT2046_MISO 39 // T_OUT
#define XPT2046_CLK 25 // T_CLK
#define XPT2046_CS 33 // T_CS

SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);

int x, y, z;

void printTouchToSerial(int touchX, int touchY, int touchZ) {
Serial.print("X = ");
Serial.print(touchX);
Serial.print(" | Y = ");
Serial.print(touchY);
Serial.print(" | Pressure = ");
Serial.print(touchZ);
Serial.println();
}

void setup() {
Serial.begin(38400);
touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreenSPI);
touchscreen.setRotation(1);
while (!Serial && (millis() <= 1000));
}



void loop() {
if (touchscreen.tirqTouched() && touchscreen.touched()) {
// Get Touchscreen points
TS_Point p = touchscreen.getPoint();
// Calibrate Touchscreen points with map function to the correct width and height
x = map(p.x, 200, 3700, 1, 320);
y = map(p.y, 240, 3800, 1, 240);
z = p.z;

printTouchToSerial(x, y, z);
}
}


 

Il led RGB e' controllabile tramite questo script

#define PIN_RED 4 // GPIO23
#define PIN_GREEN 16 // GPIO22
#define PIN_BLUE 17 // GPIO21

void setup() {
pinMode(PIN_RED, OUTPUT);
pinMode(PIN_GREEN, OUTPUT);
pinMode(PIN_BLUE, OUTPUT);
}

void loop() {
// color code #00C9CC (R = 0, G = 201, B = 204)
setColor(0, 201, 204);

delay(1000); // keep the color 1 second

// color code #F7788A (R = 247, G = 120, B = 138)
setColor(247, 120, 138);

delay(1000); // keep the color 1 second

// color code #34A853 (R = 52, G = 168, B = 83)
setColor(52, 168, 83);

delay(1000); // keep the color 1 second
}

void setColor(int R, int G, int B) {
analogWrite(PIN_RED, R);
analogWrite(PIN_GREEN, G);
analogWrite(PIN_BLUE, B);
}

Attaccando uno speaker esterno si puo' generare un suono utilizzando un altoparlante esterno collegando ai pin che sono predisposti sul DAC 2 (GPIO 26) 

 

#define DAC_CH2 26
void setup() {

}
void loop() {
for (int deg = 0; deg < 360; deg = deg + 1) {
  dacWrite(DAC_CH2, int(128 + 64 * sin(deg * PI / 180)));
}
}

 

Per usare LVGL ho provato a passare da Arduino IDE ma ho trovato un mondo di problemi. La soluzione piu' semplice e' il progetto PlatformIO (sempre con base codice Arduino)

Si clona il progetto

git clone --recursive https://github.com/rzeldent/esp32-smartdisplay-demo

in seguito si toglie il commento in platformio.ini in corrispondenza della propria scheda (ci sono molti modelli con differenti risoluzione e touch sia capacitivi che resistivi) e si fa il build

[platformio]
#default_envs = esp32-1732S019C
#default_envs = esp32-1732S019N
#default_envs = esp32-2424S012C
#default_envs = esp32-2424S012N
#default_envs = esp32-2432S022N
#default_envs = esp32-2432S022C
#default_envs = esp32-2432S024C
#default_envs = esp32-2432S024N
#default_envs = esp32-2432S024R
default_envs = esp32-2432S028R
#default_envs = esp32-2432S028Rv2
#default_envs = esp32-2432S028Rv3

Per personalizzare l'interfaccia grafica non sono riuscito ad importare il progetto dentro SquareLine Studio, un programma per creare interfacce di LVGL (il programma non e'stabile in nessuna delle versioni ed ha la necessita' di funzionare con sudo sotto Linux per non meglio chiariti motivi)

Per aggirare il problema ho creato un progetto ex novo Arduino in SquareLine


impostante le dimesioni dello schermo a 320x240x16 colori e nominando la prima finestra scrMain

Dopo aver testato l'interfaccia ho esportato la UI ho copiato il folder /scr/ui nel folder ui di esp32-smartdisplay-demo






 

lunedì 13 aprile 2020

Da Arduino ad Internet tramite Android

Avevo la necessita' di collegare una Arduino Nano 33 BLE ad internet ma non avevo molte idee quando ho pensato di usare come ponte un telefono Android

La Arduino e' contenuta nella scatolina bianca 

Per leggere i dati della porta seriale di Arduino ho collegato un cavo OTG alla USB di Android usando la libreria https://github.com/felHR85/UsbSerial. I dati poi sono stati inviati in HTTP Get tramite OKHttp. Il progetto della applicazione Android si trova sul mio GitHub https://github.com/c1p81/Seriale (si tratta di una modifica dell'esempio della libreria UsbSerial)

Questo e' invece lo skecth Arduino

=========================================================
#include <Arduino_LSM9DS1.h>
#include <Arduino_HTS221.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_APDS9960.h>

int conteggio;

void setup() {
  conteggio = 0;
  Serial.begin(9600);
  while (!Serial);

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  if (!HTS.begin()) {
    Serial.println("Failed to initialize humidity temperature sensor!");
    while (1);
  }

  
  if (!BARO.begin()) {
    Serial.println("Failed to initialize pressure sensor!");
    while (1);
  }

   if (!APDS.begin()) {
    Serial.println("Error initializing APDS9960 sensor.");
  }

}

void loop() {
  float  x, y, z;
  double dx,dy,dz;
  double mx,my,mz;
  double fx,fy,fz;
  double pitch,roll = 0.0;
  double mpitch,mroll = 0.0;
  const float alpha = 0.5;

  float pressure = BARO.readPressure();
  float temperature = HTS.readTemperature();
  float humidity    = HTS.readHumidity();

   while (! APDS.colorAvailable()) {
    delay(5);
  }
  int r, g, b, light_int;

  APDS.readColor(r, g, b, light_int);

  

  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);
    dx = (double)x;
    dy = (double)y;
    dz = (double)z;
    
    mx = mx + dx;
    my = mx + dy;
    mz = mx + dz;
    
    fx = (dx*alpha) + (fx*(1-alpha));
    fy = (dy*alpha) + (fy*(1-alpha));
    fz = (dz*alpha) + (fz*(1-alpha));

    conteggio++;
  }

  if (conteggio > 10000)
      {
        mx = mx /conteggio;
        my = my /conteggio;        
        mz = mz /conteggio;
        
        roll = atan2(fy,fz)*57.29577;
        pitch = atan2(-fx,sqrt((fy*fy)+(fz*fz)))*57.29577;

        mroll = atan2(my,mz)*57.29577;
        mpitch = atan2(-mx,sqrt((my*my)+(mz*mz)))*57.29577;

        Serial.println(String(mpitch)+";"+String(mroll)+";"+String(pitch)+";"+String(roll)+";"+String(temperature)+";"+String(humidity)+";"+String(pressure)+";"+String(light_int));
        conteggio = 0;
        fx = fy = fz = 0;
        mx = my = mz = 0;
      
      }

  
  delay(10);
  //delay(5000);
}

=========================================================
I dati sono plottati sul server mediante JSCanvas. Gli script si trovano qui https://github.com/c1p81/Seriale/tree/master/app/seriale_html













venerdì 31 gennaio 2020

Tensorflow Lite su Arduino Ble 33

A questo link e' comparso un interessante esempio su come utilizzare i sensori (accelerometro e giroscopio) di una Arduino BLE per addestrare una rete neurale con Tensorflow Lite e poi utilizzare la stessa libreria per classificare le gesture sempre tramite  Arduino



Per prova ho inserito la Arduino sotto ad un guanto (per tenerla bloccata) e poi registrando un centinaio di rotazione del polso verso l'interno e verso l'esterno


L'ultima modifica che ho apportato e' di modificare a 50 il numero di campioni per gesture
Una volta salvata due file csv (uno per movimento) ho utilizzato questo Colab per creare il file model. h


Grafico accelerazione di riferimento
Come si deve dai grafici l'errore del modello in train/validation e' estremamente ridotto

Grafico giroscopi di riferimento

Training and validation loss


Stesso grafico precedente eliminando i primi 100 dati


Risultati validazione

Il risultato del Notebook sono un file di modello di Tensorflow Lite ed un file model.h che deve essere copiato nello sketch ImuClassifier per fare il deploy del modello

Devo ammettere che il sistema funziona ma e' lontano dall'essere perfetto. Devo ancora capire se e' un problema di posizionamento del sensore durante le varie proprie (che per ovvi motivi non e' sempre identico) od un addestramento errato




lunedì 27 gennaio 2020

BLE Write Characteristic da Android

Dopo il precedente tentativo di leggere una caratteristica BLE da Python adesso un tentativo di scrivere una caratteristica (lo so e' una brutta traduzione) da Android su un dispositivo BLE

Lo sketch Arduino e' stato modificato per esporre una caratteristica 2A30 in modalita' lettura/scrittura, settare il valore a 3, leggere il valore e se e' differente da 3 spengere il Led di Arduino

=================================================================
#include <ArduinoBLE.h>

BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify); 
BLEUnsignedCharCharacteristic scrittura("2A30",BLERead | BLEWrite); 


long previousMillis = 0;  
byte test =3 ;

void setup() {
  Serial.begin(9600);  
  while (!Serial);
  pinMode(LED_BUILTIN, OUTPUT); 
  if (!BLE.begin()) {
    while (1);
  }

  BLE.setLocalName("Random");
  BLE.setAdvertisedService(numero); 
  numero.addCharacteristic(casuale);
  numero.addCharacteristic(scrittura);
  
  BLE.addService(numero); 
  casuale.writeValue(0); // set initial value for this characteristic
  scrittura.writeValue(2);
  BLE.advertise();
}

void loop() {
  int i = 0;
  BLEDevice central = BLE.central();
  if (central) {
    while (central.connected()) {
      long currentMillis = millis();
      if (currentMillis - previousMillis >= 20) {
        previousMillis = currentMillis;
        scrittura.readValue(test);
        if(test ==3)
            {
            Serial.println(test);
            digitalWrite(LED_BUILTIN, HIGH);
            }
            else
            {
            Serial.println(test);
            digitalWrite(LED_BUILTIN, LOW);
            }
            
      }
    }
    digitalWrite(LED_BUILTIN, LOW);    
  }
}

=================================================================

Per Android ho usato la libreria a questo indirizzo . Ne esistono di piu' complete ma
in questo caso avevo bisogno di semplicita'
=================================================================
package com.ble.ellamma.ble;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.ble.ellamma.bleand.Ble;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private static final String MAC_ADDRESS = "ED:CB:86:2A:68:C1";    private static final UUID BLE_NOTIFY_CHARACTER =  UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb");    //.00002a19-0000-1000-8000-00805f9b34fb--18
    private static final UUID BLE_SERVICE = UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb");
    private static final UUID CLIENT_CCD =  UUID.fromString("00002a30-0000-1000-8000-00805f9b34fb");

    ArrayList<String> getDevicess;    List<BluetoothDevice> getConnectedDevicess;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        setContentView(R.layout.activity_main);
        getDevicess = new ArrayList<>();        
        getConnectedDevicess = new ArrayList<>();
        Ble ble = new Ble(this,getApplicationContext(),".Myreceiver");
        ble.enableBle();        
        //ble.scanLeDevice(true,1000);        
        //ble.getDevices();

        ble.connectBLE(MAC_ADDRESS);        
        byte dati[] = "A".getBytes();        
        ble.writeCharacteristics(dati,BLE_SERVIVE,CLIENT_CCD,true);        
        ble.disConnectBLE();
    }

    public void onReceive(Context context, Intent intent) {
        //String data = intent.getStringExtra("data");        
        //Log.w("Luca", "Request Recieved On MyReciever ::" + data);
    }

}





giovedì 23 gennaio 2020

BLE Arduino Nano 33

Un eesmpio di scambio dati via Bluetooth LE tra una scheda Arduino Nano 33 BLE ed un PC



La Arduino Nano BLE 33 e' una scheda interessante perche' oltre al Bluetooth LE sono disponibili una IMU (LMS9DS1), un microfono digitale (MP34DT05), un sensore di colore e prossimita' (APDS9960), un sensore di pressione atmosferica (LPS22HB), un sensore di umidita' relativa e temperatura (HTS221)

Lo sketch su Arduino apre un servizio su BLE con numero 180F ed una caratteristica 2A19 in cui vengono salvati i dati di un contatore progressivo da 0 a 255 (questo per fare in modo che sul lato PC si sia in grado di vedere se si perdono pacchetti)

Lato Arduino
================================================
#include <ArduinoBLE.h>

BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify); 

long previousMillis = 0;  

void setup() {
  Serial.begin(9600);  
  while (!Serial);
  pinMode(LED_BUILTIN, OUTPUT); 
  if (!BLE.begin()) {
    while (1);
  }

  BLE.setLocalName("Random");
  BLE.setAdvertisedService(numero); 
  numero.addCharacteristic(casuale); 
  BLE.addService(numero); 
  casuale.writeValue(0); // set initial value for this characteristic
  BLE.advertise();
}

void loop() {
  int i = 0;
  BLEDevice central = BLE.central();
  if (central) {
    digitalWrite(LED_BUILTIN, HIGH);
    while (central.connected()) {
      long currentMillis = millis();
      if (currentMillis - previousMillis >= 20) {
        i++;
        casuale.writeValue(i%255);
        previousMillis = currentMillis;
      }
    }
    digitalWrite(LED_BUILTIN, LOW);    
  }
}
================================================

Per verificare che i dati vengano inviati correttamente si puo' usare gattool

================================================
gatttool -b ED:CB:86:2A:68:C1 -I
[ED:CB:86:2A:68:C1][LE]> connect
Attempting to connect to ED:CB:86:2A:68:C1
Connection successful
[ED:CB:86:2A:68:C1][LE]> char-read-uuid 2A19
handle: 0x000b value: 41
================================================

A questo punto con la libreria Bluepy si possono leggere i dati inviati dalla Arduino

================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral

addr = "ED:CB:86:2A:68:C1"
conn = Peripheral(addr, "public")

print ("-Servizi")
services = conn.getServices()
for service in services:
print(service.uuid)


print("-Caratteristica")
charac_dic = service.getCharacteristics()
for charac in charac_dic:
print(charac.uuid)
if charac.uuid == "2a19":
print ("Trovata")
Data_char = charac
print(Data_char)
Data_handle = Data_char.getHandle()
print Data_handle
while True:
print (ord(charac.read()))
================================================

la trasmissione dati in questo modo e' piuttosto lenta..circa un dato ogni decimo di secondo.
Usando la tecnica di subscribe and notify la Arduino invia i dati al PC senza la necessita' per quest'ultimo di richiederli. Con questa tecnica non si perde nessun pacchetto

================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral
import struct

def listAll(p):
for svc in p.getServices():
print(svc.uuid.getCommonName())
for ch in svc.getCharacteristics():
print(" " + str(ch.valHandle) + ": " + ch.uuid.getCommonName())

class MyDelegate(btle.DefaultDelegate):
    def __init__(self):
        btle.DefaultDelegate.__init__(self)

    def handleNotification(self, cHandle, data):
print(ord(data))

addr = "ED:CB:86:2A:68:C1"
p = btle.Peripheral(addr,"public")
services=p.getServices()
for service in services:
   print(service.uuid)

p.setDelegate( MyDelegate() )

listAll(p)

svc = p.getServiceByUUID("0000180f-0000-1000-8000-00805f9b34fb")
ch = svc.getCharacteristics()[0]
p.writeCharacteristic(ch.valHandle+1, b'\x01\x00', withResponse=True)

while True:
    if p.waitForNotifications(1.0):
        continue
    print "Waiting..."

venerdì 1 novembre 2019

Cross compilare da Debian per Arduino Yun

Seguendo il precedente post su come poter continuare ad usare Yun nonostante il supporto end-of-life sono riuscito a settate la possiblita' di effettuare la cross compilazione da Debian verso Yun

Per prima cosa si scarica Buildroot  e lo si  configura (make menuconfig) con target MIPS big endian, ELF MIPS32 con toolchain uCLIb abilitando con Gdb per futuri sviluppi. Fatto cio' si lancia make e si aspetta

A questo punto per rendere piu' semplice la cross compilazione si usa Eclipse CDT
Si crea un nuovo progetto C con Cross GCC e si lasciano in bianco GCC Cross Command che saranno compilati in seguito

Si aprono quindi le proprieta' del progetto Eclipse selezionando Cross GCC in ToolChain Editor


Si setta come Prefix (attenzione al meno finale che deve essere incluso) e Path

mips-buildroot-linux-uclibc-
/home/luca/Downloads/buildroot-2019.02.6/output/host/usr/bin



A questo punto C Build Settings/Includes si include la directory

/home/luca/Downloads/buildroot-2019.02.6/output/host/usr/include  

tutti i file necessari si trovano nella sottodirectory /output/host/ di Buildroot



Si aggiungono due pathe per le librerie

/home/luca/Downloads/buildroot-2019.02.6/output/host/usr/lib
/home/luca/Downloads/buildroot-2019.02.6/output/host/mips-buildroot-linux-uclibc/lib



Arrivati fino a qui si puo' compilare il file e copiarlo in scp sulla Yun

Opencv camera calibration in cpp

Oltre che con uno script Python come visto qui la calibrazione della camera si puo' fare anche con il programma in CPP Questo il proce...