Lidar Lite 1 - sensore laser

Ciao ,

vorrei chiedere info a chi utilizza il Lidar lite 1( anche ad Astrobeed se ha tempo :slight_smile: )
Sto scrivendo uno sketch per utilizzare un motore passo passo con sopra montato un Lidar.

Purtroppo ora non posso postare lo sketch.
Ho notato che come da datasheet occorrono almeno 20ms per leggere la distanza rilevata.Infatti funziona.

Pi√Ļ tardi ho provato ad usare il polling ma con mia sopresa , probabilmente sbaglio qualcosa , il tempo impiegato √® molto pi√Ļ elevato

Sta sera posterò il codice per chi interessato al mio problema , nel frattempo provo a chiedere a qualcuno di voi se ha avuto esperienza con questo oggetto :slight_smile:

Grazie mille,
ciao

Attenzione che all’accensione il lidar lite parte sempre con i parametri di default, tra cui la velocità massima che è solo 10 Hz, è indispensabile settare la velocità di scansione e l’offset dell’errore (se vuoi misure precise), da trovare empiricamente con delle misure campione.
Adesso sono fuori (scampagnata) e non ho con me il codice che utilizzo con questi sensori, rientro domani e lo posto così hai tutto l’init pronto già predisposto per le varie velocità di scansione.

sei un grande , grazie :slight_smile:

Questa è la funzione che chiamo ogni volta che voglio far girare in senso orario il motorino.
Non ha alcun parametro sin’ora , id è global ad esempio, non ritorna nessun valore e forse è poco leggibile.
Quello che voglio fare per’ora e leggere la distanza ad ogni passo.
Ogni passo è impostato sui 15ms totali contando solo i delay().
Forse con il polling e i dovuti settaggi come hai suggerito riesco a fare tutto nei tempi

vado a leggermi meglio il manuale

void motorR()
{ 

  int bitMask=B00001111; 

      PORTB = (PORTB &~bitMask) |  modeR[id]; 
       
      I2c.write(LIDARLite_ADDRESS,0x00, 0x04);    
      delay(wait);
              
      I2c.read(LIDARLite_ADDRESS,0x8F, 2, myArray); 
      delay(wait2);
              
      distance = (myArray[0] << 8) + myArray[1];  
              
              //Serial.println(distance);  //debug
              id++;          
              if (id >3) id = 0;
}

con il polling

void motorF(){ 
  int bitMask=B00001111; 
  int  rd =100;
              PORTB = (PORTB &~bitMask) |  modeF[id]; 
              while (rd !=0) {
                  rd = I2c.write(LIDARLite_ADDRESS,0x00, 0x04);
                  delay(2);  
              }
              rd = 100;
              while (rd!=0){
                  rd = I2c.read(LIDARLite_ADDRESS,0x8F, 2, myArray);
                  delay(2);  
              }
              distance = (myArray[0] << 8) + myArray[1];    
              Serial.println(distance);
              id++;          
              if (id >3) id = 0;
              
}

da trovare empiricamente con delle misure campione

Domanda forse banale , come faccio a verificare una misura non campione se non vedo dove punto il laser?
Ad esempio vorrei verificare la distanza che c’e tra il sensore il cui punto di riferimento se ho capito bene è la parte posteriore (pcb) ed un oggetto ( es. scatola) obliqua rispetto al beam

add info:

#define acq_Count_reg   2

  I2c.write(LIDARLite_ADDRESS,acq_Count_reg, 8);    // Write to LIDAR-Lite Address with Value
  delay(20);

ora √® quattro volte pi√Ļ veloce ma non credo sia questo il registro giusto.
Probabilmente o configurato il numero di sample (?)

control_reg [2] Maximum acquisition count sets the maximum number of acquisition cycles
with a maximum value of 255. In most cases an acquisition of 128 is
adequate.

Ecco il codice per inizializzare correttamente il Lidar Lite e leggere la distanza.

Il valore da assegnare a ‚ÄúCalibrationOffsetVlue‚ÄĚ devi trovarlo con una misura su una distanza nota, p.e. 50 cm, riferita ad un ben preciso punto del sensore, p.e il fondo, la differenza tra la misura e la distanza reale √® l‚Äôoffset, √® una costante per tutto il range di misura del lidar, -5 √® il valore medio di questo parametro e dovrebbe andare bene per il tuo lidar.

‚ÄúMeasurementPeriod‚ÄĚ √® il parametro che definisce quanti ms dura il ciclo di acquisizione e di conseguenza la frequenza di lettura, 10 ms = 100 Hz.

#include <I2C.h>
#define    LIDARLite_ADDRESS       0x62          // Default I2C Address of LIDAR-Lite.
#define    RegisterMeasure         0x00          // Register to write to initiate ranging.
#define    InterpulseSpacing       0x68          // Register velocity measurement setting
#define    MeasureValue            0x04          // Value to initiate ranging.
#define    RegisterHighLowB        0x8f          // Register to get both High and Low bytes in 1 call.
#define    CalibrationRegister     0x13          // The register to set for calibration
#define    CalibrationOffsetVlue   -5            // The calibration offset. 

// #define    MeasurementPeriod    0xC8          // 100 ms
// #define    MeasurementPeriod    0x50          // 40  ms
// #define    MeasurementPeriod    0x28          // 20  ms
#define       MeasurementPeriod    0x14          // 10  ms

boolean    Ld_Stat;

void setup()
{
  Serial.begin(115200);     //Open serial connection at 115200bps.

  pinMode(13, OUTPUT);    // led

  I2c.begin();               // Opens & joins the i2c bus as master
  delay(100);               // Waits to make sure everything is powered up before sending or receiving data
  I2c.timeOut(50);       // Set I2C timeout
  LidarLiteCalibrate();  // setup Lidar Lite
}

void loop()
{
  Ld_Stat ^= 1;
  digitalWrite(13, Ld_Stat); // lampeggio led
  Serial.println(LidarLiteRawDistance());
  delay(100); // delay 100 ms, vengono visualizzate solo 10 letture ogni secondo
}

/*=====================================================================================
  FUNCTIONS
  =====================================================================================*/

// imposta offset e perido misura
void LidarLiteCalibrate()
{
  uint8_t nackack = 100; // Setup variable to hold ACK/NACK responses
  // While NACK keep going (i.e. continue polling until sucess message (ACK) is received )
  while (nackack != 0)
  {
    nackack = I2c.write(LIDARLite_ADDRESS, CalibrationRegister, CalibrationOffsetVlue); // Write Calibration Offset Value to 0x13
    delay(1); // Wait 1 ms to prevent overpolling
  }

  nackack = 100;
  while (nackack != 0)
  {
    nackack = I2c.write(LIDARLite_ADDRESS, InterpulseSpacing, MeasurementPeriod); // Write Velocity measurement period to 0x68
    delay(1); // Wait 1 ms to prevent overpolling
  }
  // MeasurementPeriod
}


// legge distanza lidar lite
int LidarLiteRawDistance()
{
  // Write 0x04 to register 0x00
  uint8_t nackack = 100;
  while (nackack != 0)
  {
    nackack = I2c.write(LIDARLite_ADDRESS, RegisterMeasure, MeasureValue); // Write 0x04 to 0x00
    delay(1); // Wait 1 ms to prevent overpolling
  }
  byte distanceArray[2]; // array to store distance bytes from read function
  // Read 2byte distance from register 0x8f
  nackack = 100; // Setup variable to hold ACK/NACK responses
  while (nackack != 0)
  {
    nackack = I2c.read(LIDARLite_ADDRESS, RegisterHighLowB, 2, distanceArray); // Read 2 Bytes from LIDAR-Lite Address and store in array
    delay(1); // Wait 1 ms to prevent overpolling
  }
  int distance = (distanceArray[0] << 8) + distanceArray[1];  // Shift high byte [0] 8 to the left and add low byte [1] to create 16-bit int
  return distance; // give us this value
}

Ottimo grazie mille ,
Unica cosa sto provando a rileggere cosa ho scritto in 0x68 , ma mi resituisce sempre 0.
Avevo già provato con il registro 0x3 e funzionava perfettamente

Un’altra cosa , sai se la configurazione risiede su una eeprom interna oppure è solo ram ?
ciao grazie

Edit:
Sto provando , e noto che con il polling è peggiorativo rispetto alla pausa

 byte tmp[2];

  nackack = 100; 
  while (nackack != 0)
  {
    nackack = I2c.read(LIDARLite_ADDRESS,InterpulseSpacing,1,tmp);
    delay(2);

  }
    
    int u = (tmp[0] << 8) + tmp[1];  

    Serial.println(u);