mercoledì 23 gennaio 2019

Wakeup Arduino Uno con interrupt da MPU6050

L'accelerometro MPU6050 (altrimenti conosciuto come Gy-521) ha un pin interrupt che puo' essere programmato per risvegliare una Arduino Uno
Ho semplificato un po' il codice ritrovato a questo link


si possono personalizzare le soglie di attivazione dell'interrupt modificando il valore di MOT_THR e MOT_DUR


-----------------------------------------------------------------------
#include <avr/sleep.h>  
#include <Wire.h>


#define SIGNAL_PATH_RESET  0x68
#define I2C_SLV0_ADDR      0x37
#define ACCEL_CONFIG       0x1C 
#define MOT_THR            0x1F  // Motion detection threshold bits [7:0]
#define MOT_DUR            0x20  // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
#define MOT_DETECT_CTRL    0x69
#define INT_ENABLE         0x38
#define WHO_AM_I_MPU6050   0x75 // Should return 0x68
#define INT_STATUS 0x3A
//when nothing connected to AD0 than address is 0x68
#define ADO 0
#if ADO
#define MPU6050_ADDRESS 0x69  // Device address when ADO = 1
#else
#define MPU6050_ADDRESS 0x68  // Device address when ADO = 0
#endif

int wakePin = 2;                 // pin used for waking up  


void wakeUpNow() 
{       
}  


void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
  Wire.begin();
  Wire.beginTransmission(address);  // Initialize the Tx buffer
  Wire.write(subAddress);           // Put slave register address in Tx buffer
  Wire.write(data);                 // Put data in Tx buffer
  Wire.endTransmission();           // Send the Tx buffer
}

uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data;                            // `data` will store the register data   
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address 
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}


void setup() 
{  
    Serial.begin(9600);
    writeByte( MPU6050_ADDRESS, 0x6B, 0x00);
    writeByte( MPU6050_ADDRESS, SIGNAL_PATH_RESET, 0x07);//Reset all internal signal paths in the MPU-6050 by writing 0x07 to register 0x68;
    writeByte( MPU6050_ADDRESS, I2C_SLV0_ADDR, 0x20);//write register 0x37 to select how to use the interrupt pin. For an active high, push-pull signal that stays until register (decimal) 58 is read, write 0x20.
    writeByte( MPU6050_ADDRESS, ACCEL_CONFIG, 0x01);//Write register 28 (==0x1C) to set the Digital High Pass Filter, bits 3:0. For example set it to 0x01 for 5Hz. (These 3 bits are grey in the data sheet, but they are used! Leaving them 0 means the filter always outputs 0.)
    writeByte( MPU6050_ADDRESS, MOT_THR, 20);  //Write the desired Motion threshold to register 0x1F (For example, write decimal 20).  
    writeByte( MPU6050_ADDRESS, MOT_DUR, 40 );  //Set motion detect duration to 1  ms; LSB is 1 ms @ 1 kHz rate  
    writeByte( MPU6050_ADDRESS, MOT_DETECT_CTRL, 0x15); //to register 0x69, write the motion detection decrement and a few other settings (for example write 0x15 to set both free-fall and motion decrements to 1 and accelerometer start-up delay to 5ms total by adding 1ms. )   
    writeByte( MPU6050_ADDRESS, INT_ENABLE, 0x40 ); //write register 0x38, bit 6 (0x40), to enable motion detection interrupt.     
    writeByte( MPU6050_ADDRESS, 0x37, 160 ); // now INT pin is active low

    pinMode(2, INPUT);        // sets the digital pin 7 as input
    pinMode(wakePin, INPUT_PULLUP);  // wakePin is pin no. 2
}  

void sleepNow() 
{  
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    
    sleep_enable();                        
    delay(500);  
    attachInterrupt(0,wakeUpNow, LOW); 
    delay(500);
    sleep_mode();     

     //ritorno da interrupt
     delay(500);

     sleep_disable();         
     delay(500);  
     detachInterrupt(0);   
                                
}  

uint16_t readdata;
void loop() 
{     
      sleepNow();     
      /*readdata = readByte(MPU6050_ADDRESS,0x3A);
      Serial.print(readdata);Serial.print("-");
      readdata = readByte(MPU6050_ADDRESS,0x37);
      Serial.println(readdata);*/
      Serial.println("Movimento registrato");     

}  

Livello Automatico Stanley AL24

Questo livello viene venduto in kit con il treppiede e la stadia da 5 m. E' uno strumento economico e di prestazioni adeguate al prezzo....l'unica cosa veramente strana e' che la stadia non presenta la bolla circolare

La distanza massima tra due punti e' di circa 50-60 m (considerando la posizione del cannochiale al centro tra i due punti)



Per misurare le distanze si usano i due riferimenti al di sopra ed al di sotto del crocefilo. Per esempio nell'immagine sotto riportate le misure sono circa 1,395 e 1,265. La distanza della stadia (dato il rapporto 1:100) puo' essere calcolata come 1,395-1,265=0,13*100 = 13 m

La stadia non e' verticale ma ero da solo ;>

Persistenza delle variabili in Alexa Skills

La persistenza delle variabili in Alexa Skills con NodeJS si ottiene tramite PersistantAttributes che si appoggia su DynamoDB in modo trasparente



In questa prima fase viene settata una variabile (per semplicita' statica) in modo persistente. Se non e' settata crea una nuova stringa. Importante impostare la chiamata come asincrona

Da notare che le variabili sono relative ad un determinato account per cui ogni utente ritrovera' le proprie impostazioni

---------------------------------------------------------------------------
const LaunchRequestHandler = {
  canHandle(handlerInput) {
     return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    
  },
  
  async handle(handlerInput) {    
    const attributesManager = handlerInput.attributesManager;
    var speechText = "Benvenuto nella skill ";

    const attributes = await attributesManager.getPersistentAttributes() || {};

    if (Object.keys(attributes).length === 0) {
      attributes.nameValue = "Luca";
      attributesManager.setPersistentAttributes(attributes);
      await attributesManager.savePersistentAttributes();
    }else {
      speechText = "Benvenuto  ${attributes.nameValue.toString()}";
    }
    
    return handlerInput.responseBuilder
      .speak(speechText)
      .withShouldEndSession(false)
      .getResponse();
  },
};
---------------------------------------------------------------------------


Con questo codice si puo' richiamare il valore della variabile da altra intent

---------------------------------------------------------------------------
 const attributesManager = handlerInput.attributesManager;
  const attributes = await attributesManager.getPersistentAttributes()
  var speechOutput =  attributes.nameValue.toString();
---------------------------------------------------------------------------

Per salvare i dati e' necessario impostare il nome della tabella in cui sono salvate le variabili e la possibilita' di creare in automatico la tabella ove non esista
---------------------------------------------------------------------------
const skillBuilder = Alexa.SkillBuilders.standard();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    YesHandler,
    geo,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .withTableName('alexa-data')
  .withAutoCreateTable(true)
  .lambda();
---------------------------------------------------------------------------


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