mercoledì 12 settembre 2018

ESP32 Lolin Lite Captive Portal

Dopo il Wemos TTGO ho provato Lolin 32 Lite. Nonostante sia un prodotto non piu' in produzione risulta interessante



I driver per la seriale virtuale sono relativi al CH340


Da misure fatte da altre persone sembra che il consumo sia di circa 800 microA in sleep mode e di circa 50 mA in modalita' normale

Una delle caratteristiche piu' interessanti e' che si puo' alimentare tramite una LiPo tramite JST PH-2 2.0mm e c'e' montato anche un circuito di ricarica che, nel caso di collegamento USB, va a ricaricare la LiPo

Ho provato a montare lo skect ESP32 di Captive Portal (negli esempi sotto DNSServer) ma per rendere la cosa non banale ho provato ad inserire una immagine nella home. Di fatto non esiste un file system e per includere la img ho preso un file (a caso ;>), lo ho convertito in BASE 64 tramite questa pagina e poi ho incollato la conversione nello sketch come segue

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


#include <WiFi.h>
#include <DNSServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);

String responseHTML = ""
  "<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
  "<h1>Hello World!</h1><p>This is a captive portal example. <br>"
   "<img src='data:image/jpg;base64,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'/>"
   "</body></html>";

void setup() {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("CaptivePortal");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  server.begin();
}

void loop() {
  dnsServer.processNextRequest();
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {
    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(responseHTML);
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
  }
}
---------------------------------------------------------

Il risultato e' il seguente



venerdì 7 settembre 2018

Wemos TTGO Wifi BT ESP32

Questa scheda di sviluppo integrata diversi aspetti interessanti: un microprocessore ESP32, WiFi, Bluetooth 4,schermo OLED SSD1306 da 0.96" ed un alloggiamento per una batteria LiPo tipo 18650 con circuito di ricarica integrato

Per aggiungere la scheda all'Arduino IDE si deve scaricare il pacchetto


https://dl.espressif.com/dl/package_esp32_index.json
inoltre potrebbero essere necessari i driver per la porta seriale via USB scaricabili da qui
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

Questo e' il pinout della scheda

Una cosa che mi ha fatto impazzire e' che nonostante questi settaggi abbastanza conservativi non riuscivo a fare l'upload sulla scheda (con il messaggio di errore  

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

Il trucco e' quello di premere il pulsante di Boot al momento di fare l'upload

Le connessioni dell'ESP 32 con l'OLED sono attraverso i seguenti pin

SCL - Pin 4
SDA - Pin 5

La libreria per controllare l'OLED si puo' scaricare da qui . I programmi di esempio della libreria devono essere modificati (per esempo SSD1306SimpleDemo) cosi'

-----------------------------------------------
#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
#include "images.h"

SSD1306  display(0x3c, 5, 4);

#define DEMO_DURATION 3000
typedef void (*Demo)(void);
-----------------------------------------------

Questo e' invece un semplice WiFi Scanner (unione di due esempi) che mostra i dati a display 


----------------------------------------------
#include "WiFi.h"
#include "SSD1306.h"

SSD1306  display(0x3c, 5, 4);


void setup()
{

    pinMode(16,OUTPUT);
    digitalWrite(16, LOW);    
    delay(50); 
    digitalWrite(16, HIGH); 
    Serial.begin(115200);

    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);

    display.init();

    display.flipScreenVertically();
    display.setFont(ArialMT_Plain_10);

    Serial.println("Setup done");
}

void loop()
{
    display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
 
    Serial.println("scan start");

    int n = WiFi.scanNetworks();
    Serial.println("scan done");
    if (n == 0) {
        Serial.println("no networks found");
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        for (int i = 0; i < n; ++i) {
            // Print SSID and RSSI for each network found
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            display.drawString(0, (10*i),WiFi.SSID(i)+" "+WiFi.RSSI(i));
            display.display();

            delay(10);
        }
    }
    Serial.println("");

    delay(5000);
}

lunedì 27 agosto 2018

BSFrance LoRa43u4

Una scheda di sviluppo con un 32u4 (tipo Arduino) ed una radio LoRa RA-02 SX 1276 a 433 MHz

Non si vede completamente ma si intuisce che dal vertice in basso a sinistra esce l'antenna


Questo e' il pinout... la cosa interessante e' nell'angolo in basso a destra ovvero come sono connessi i pin della radio con il 32u4. Questo per poi programmare la scheda con Arduino IDE


Per aggiungere la scheda all'Arduino IDE si deve fare a mano scaricando questo file
https://quadmeup.com/wp-content/uploads/2017/10/bsfrance.zip

Questa e' invece la libreria per gestire la radio
https://github.com/sandeepmistry/arduino-LoRa

Un aspetto interessante e' che il dispositivo puo' essere alimentato con una Lipo ed ha un circuito di ricarica dal lato USB (alimentando la USB quindi si puo' ricaricare la LiPo)...inoltre il pin subito al di sotto del connettore JST denominato BAT puo' essere usato da sketch per minitorare la carica della batteria (e' necessario comunque un divisore di tensione perche' una LiPo puo' arrivare al oltre 4 V mentre i pin digitali possono reggere fino a 3.3V)

Lo sketch contenuto negli esempi della librerie deve essere modificato come segue (sia per quanto riguarda i pin che la frequenza di trasmissione)

La radio puo' essere configurata attraverso i seguenti comandi

LoRa.sleep(); spenge la radio

LoRa.setTxPower(txPower);
  cambia la potenza di trasmissione (da 0 a 20 default 17)

LoRa.setSpreadingFactor(spreadingFactor);  (da 6 a 12 default 7)

LoRa.setSignalBandwidth(signalBandwidth);

LoRa.enableCrc(); abilita il CRC sui dati


-------------------------------------------------------------
#include <SPI.h>
#include <LoRa.h>

const int csPin = 1;         
const int resetPin = 4;       
const int irqPin = 7;

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

  Serial.println("LoRa Receiver");
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin


  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

giovedì 23 agosto 2018

FFT su Arduino

Era da tanto che volevo provare ad elaborare i dati di un accelerometro in FFT con Arduino. Ora grazie a questo post ne sono venuto a capo.

Ho usato un accelerometro GY-61 con l'uscita Z connessa ad A0 ed uno schermo Oled I2C per visualizzare i dati (collegamento VCC 5V , GND, SDA -> A4, SCL -> A5).
Al momento di compilare il codice completo Arduino IDE ha segnalato che lo sketch era troppo grande ed ho dovuto eliminare l'output dei dati sulla porta seriale

Di seguito un video di esempio con la registrazione dei passi e battendo sul tavolo con la mano





--------------------------------------------------------------------------------------------
#include "arduinoFFT.h"

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(4);

#define SAMPLES 128             
#define AMPLIFICA 10

arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
    sampling_period_us = round(1000000*(1.0/100));
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

void loop() {
   
    display.clearDisplay();
    
    for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    
        vReal[i] = analogRead(0);
        vImag[i] = 0;
        while(micros() < (microseconds + sampling_period_us)){
        }
    }

    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);

      
    for(int i=2; i<(SAMPLES/2)-2; i++)  //se si fa partire i da zero si prende anche la parte continua del segnale
    {
        display.drawLine(i, 0, i, AMPLIFICA*vReal[i]*(5.0/1023.0), WHITE);
    }
    display.display();
    delay(1);  
}

PMII 34 - Mac Book Air 2009

La prima versione di Mac Book uscita (qui in versione UK con disco a piatti rotanti invece che SSD)

Quando usci' rimasi scioccato dal fatto da quanto costava e per il fatto che avesse pochissime porte (e si'...anche per il peso)...lo ho utilizzato in questi giorni e non ricordavo di quanto scaldasse..praticamente non si puo' tenere sulle ginocchia





martedì 21 agosto 2018

PMII 33 - Game Boy Color GBC

Game Boy Color. Da notare che lo schermo era talmente piccolo che esisteva un accessorio lente ingrandimento di circa X2




Could not find Developer Disk Image

Ecco un buon motivo per non usare Mac.
Sto usando un vecchio portatile MacBook Pro con installato El Capitan 10.11.6 (piu' recente sistema installabile). Per adesso lo ho usato quasi solo  come macchina da scrivere ma adesso volevo provare ad usare Cordova ed avevo la necessita' di installare XCode
Primo problema: XCode per le versioni "vecchie" non si installa da Apple Store. Si deve scaricare il pacchetto a parte (e bisogna sapere quale e' il pacchetto giusto...nel mio caso XCode 7.3.1) ma per fare cio' bisogna anche essere sviluppatori registrati e quindi aver pagato l'abbonamento

Fatto cio' ho provato a compilare un semplice codice e ad installarlo sul telefono (un iPhone SE con iOS 11.4.1) ed e' saltato fuori l'errore Could not find Developer Disk Image...e quindi ??? . Tutto cio' nonostante avessi esplicitamente messo come target IOs 9.3 ovvero il massimo per XCode 7




Dopo un bel po' di giri su Internet ho scoperto che si possono scaricare le Developer Disk Image in modo non ufficiale (ma firmate) da questo sito

https://github.com/xushuduo/Xcode-iOS-Developer-Disk-Image

e poi devono essere copiate nella cartella

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

ed alla fine funziona