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

Bluetooth LE cached name scan

Lavorando ad un progetto in cui un beacon BLE cambia spesso il proprio nome ho scoperto che la funzione ScanResult (vedi qui per esempio) non aggiorna i nomi dei beacon una volta scoperti (come se avesse una cache interna). Usando invece la funzioen ScanRecord, come nel codice sottostante, tutto funziona in modo corretto


-----------------------------
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.blescan.lucainnocenti.blescan">

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>



    <uses-feature        android:name="android.hardware.bluetooth_le"        android:required="true" />

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
-----------------------------


-----------------------------
package com.blescan.lucainnocenti.blescan;

import android.Manifest;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private BluetoothAdapter mBluetoothAdapter  = null;
    private BluetoothLeScanner mBluetoothLeScanner = null;

    public static final int REQUEST_BT_PERMISSIONS = 0;
    public static final int REQUEST_BT_ENABLE = 1;

    private boolean mScanning = false;
    private Handler mHandler = null;

    private Button btnScan = null;



    private ScanCallback mLeScanCallback =
            new ScanCallback() {

                @Override                public void onScanResult(int callbackType, final ScanResult result) {
                    super.onScanResult(callbackType, result);
                    final ScanRecord scanRecord = result.getScanRecord();


                    if (scanRecord.getDeviceName() != null) {
                        Log.d("BLE", scanRecord.getDeviceName());
                    }

                }

                @Override                public void onScanFailed(int errorCode) {
                    super.onScanFailed(errorCode);
                    Log.d("BLE", "error");
                }
            };






    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnScan = (Button) findViewById(R.id.btnScan);

        new Handler().postDelayed(new Runnable() {
            @Override            public void run() {
                if (mScanning){
                    mScanning = false;
                    scanLeDevice(false);
                    btnScan.setText("STOP");
                } else {
                    mScanning = true;
                    scanLeDevice(true);
                    btnScan.setText("SCAN");
                }
            }
        }, 30000);




        btnScan.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                onBtnScan();
            }
        });
        this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        this.mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
        this.mHandler = new Handler();

        checkBtPermissions();
        enableBt();
    }

    public void onBtnScan(){
        if (mScanning){
            mScanning = false;
            scanLeDevice(false);
            btnScan.setText("STOP");
        } else {
            mScanning = true;
            scanLeDevice(true);
            btnScan.setText("SCAN");
        }
    }

    public void checkBtPermissions() {
        this.requestPermissions(
                new String[]{
                        Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN                },
                REQUEST_BT_PERMISSIONS);
    }

    public void enableBt(){
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth        }
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_BT_ENABLE);
        }
    }

    public void scanLeDevice(final boolean enable) {
        // ScanSettings mScanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_BALANCED).setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).build();
        if (enable) {
            mScanning = true;
            Log.i("Scanning", "start");
            mBluetoothLeScanner.startScan(mLeScanCallback);
        } else {
            Log.i("Scanning", "stop");
            mScanning = false;
            mBluetoothLeScanner.stopScan(mLeScanCallback);
        }
    }
-----------------------------

venerdì 17 agosto 2018

ESP 32 Bluetooth Beacon

Avevo gia' comprato da diverso tempo una scheda da sviluppo di ESP32 (ESP-VROOM-32) ma non avevo avuto modo di trovarle un utilizzo serio.
Adesso l'ho tirata fuori per creare una sorta di beacon bluetooth programmabile. In pratica il sistema deve consumare il meno possibile (e quindi deve utilizzare lo sleep mode del processore) fino a quando viene premuto un pulsante; fino a che il pulsante e' mantenuto premuto deve attivarsi il bluetooth, al momento del rilascio del pulsante il dispositivo deve segnalare per 10 secondi che si sta spengendo (o meno che sta andando in sleep mode) e poi deve addormentarsi



Il pinout della scheda e' il seguente


Per poter programmare la scheda con Arduino IDE (su Mac) si deve eseguire il seguente comando

mkdir -p ~/Documents/Arduino/hardware/espressif && \
cd ~/Documents/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32 && \
git submodule update --init --recursive && \
cd tools && \
python get.py
Si devono installare i driver USB to UART VCP scaricabili da qui


Queste le impostazione dell'Arduino IDE. E' consigliato di usare una Flash Frequency di 40 MHz ed una Upload Speed di 115200

Ho trovato un problema (che a quanto pare e' piuttosto comune) ovvero che non sempre e' possibile caricare lo sketch via Arduino sul modulo ESP a causa dell'errore


Timed out waiting for packet header
Non so quale e' la soluzione...a forza di provare, premendo i tasti boot e reset, la scheda ritorna a funzionare




----------------------------------
#include "SimpleBLE.h"
SimpleBLE ble;

const int buttonPin = 14;    
int buttonState = 0;     
int prevState = 0;   

void setup() {
  Serial.begin(115200);

  pinMode(buttonPin, INPUT);
  Serial.println("Start");

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_14,1); //1 = High, 0 = Low
  

}

void loop() {
  buttonState = digitalRead(buttonPin);

  if ((buttonState == HIGH)  && (prevState == 0)) {
    Serial.println("Start BLE");
    prevState = 1;
    ble.begin("ESP32");
  }

  if ((buttonState == LOW)  && (prevState == 1)) {
    Serial.println("Stop BLE");
    ble.end();
    delay(2000);
    ble.begin("ESP32 OFF");
    delay(10000);
    ble.end();
    Serial.println("Sleep Mode");
    delay(1000);
    prevState = 0,
    esp_deep_sleep_start();
  }
----------------------------------

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...