Совместная работа TOF и сервопривода
Совместная работа TOF и сервопривода

Продолжаю работу над реализацией радара на базе лазерного датчика.

После замены УЗД, из-за его большой погрешности по углу луча, на лазерный датчик с узконаправленным лучом у меня возникли проблемы со срывом цикла поворота сервопривода при считывание данных с датчика.

Тогда я предпринял попытку разнести управление сервоприводом и считывание данных с датчика на разные платы. Это дало положительный результат, но нужно было синхронизировать поворот сервопривода и получение измерения.

Плата с сервоприводом была определена, как master, а плата с датчиком, как slave. 

Логика получения данных с датчика следующая:

  • Master после поворота на нужный угол отправляет запрос на slave по  Wire.begin(8);       /* инициализация I2C Master */
  • Slave получает запрос в void setup() Wire.begin(8);
  • Slave запускает код, который вычисляет расстояние, передает master по  I2C символ о готовности к передаче данных, в данном случае код "2" и по SoftwareSerial art1(9,8); передаем растояние разбитое надва байта.
  • Master получает код "2"  Wire.requestFrom(8, 1); /* Запрос на получение подтверждения   */
  • Если код получен то получаем два байта  byte v1 = uart1.read();    byte v2 = uart1.read(); и собираем значение TOF_distance = v1 | (v2<<8);

    Это позволило получать стабильный результат, но с некоторыми проверками.

    В код считывания данных с датчика пришлось добавить функцию проверки получения замера, т.к. if (uart2.available()>=32) не всегда возвращала результат, для этого надо сделать несколько повторений до получения результата.

    За основу работы с датчикам использовался код

  • /*
  • TOF ranging test

  •  
  • Receives from serial port 1, sends to the main serial (Serial 0).

  •  
  • This example works only with boards with more than one serial like Arduino Mega, Due, Zero etc.

  •  
  • The circuit:
  • - TOF Laser Range Sensor attached to Serial port 1
  • - Serial Monitor open on Serial port 0

  •  
  • created 27 July 2020
  • by kaloha [Waveshare] https://www.waveshare.com/

  •  
  • This example code is in the public domain.
  • */
  • #include <HardwareSerial.h> //[6](https://sigmdel.ca/michel/ha/esp8266/super_mini_esp32c3_en.html)[12](https://www.luisllamas.es/en/esp32-uart/)

  •  
  • HardwareSerial Serial2(1); // Создаём объект для Serial1

  •  
  • unsigned char TOF_data[32] = {0};   //store 2 TOF frames
  • unsigned char TOF_length = 16;
  • unsigned char TOF_header[3] {0x57,0x00,0xFF};
  • unsigned long TOF_system_time = 0;
  • unsigned long TOF_distance = 0;
  • unsigned char TOF_status = 0;
  • unsigned int TOF_signal = 0;
  • unsigned char TOF_check = 0;

  •  
  • void setup() {
  • // initialize both serial ports:
  • Serial.begin(115200);
  • Serial2.begin(9600, SERIAL_8N1, 0, 1); // Указываем RX и TX
  • }

  •  
  • bool verifyCheckSum(unsigned char data[], unsigned char len){
  • TOF_check = 0;

  •  
  • for(int k=0;k<len-1;k++)
  • {
  •    TOF_check += data[k];
  • }

  •  
  • if(TOF_check == data[len-1])
  • {
  •    Serial.println("TOF data is ok!");
  •    return true;    
  • }else{
  •    Serial.println("TOF data is error!");
  •    return false;  
  • }

  •  
  • }

  •  
  • void loop() {
  • Serial.println("read from port 1");
  • // read from port 1:
  • if (Serial2.available()>=32) {//проверяет, есть ли в буфере приёма второго аппаратного последовательного порта (Serial2) не менее 32 байт доступных для чтения данных.
  •   for(int i=0;i<32;i++)
  •   {
  •     TOF_data[i] = Serial2.read();// записываем данные из порта в массив
  •   }
  •  
  •  for(int j=0;j<16;j++)
  •  {
  •    if( (TOF_data[j]==TOF_header[0] && TOF_data[j+1]==TOF_header[1] && TOF_data[j+2]==TOF_header[2]) && (verifyCheckSum(&TOF_data[j],TOF_length)))
  •    {
  •      if(((TOF_data[j+12]) | (TOF_data[j+13]<<8) )==0)
  •      {
  •         Serial.println("Out of range!");
  •       }else{
  •         Serial.print("TOF id is: ");
  •         Serial.println(TOF_data[j+3],DEC);
  •  
  •         TOF_system_time = TOF_data[j+4] | TOF_data[j+5]<<8 | TOF_data[j+6]<<16 | TOF_data[j+7]<<24;
  •         Serial.print("TOF system time is: ");
  •         Serial.print(TOF_system_time,DEC);
  •         Serial.println("ms");
  •  
  •         TOF_distance = (TOF_data[j+8]) | (TOF_data[j+9]<<8) | (TOF_data[j+10]<<16);
  •         Serial.print("TOF distance is: ");
  •         Serial.print(TOF_distance,DEC);
  •         Serial.println("mm");
  •  
  •         TOF_status = TOF_data[j+11];
  •         Serial.print("TOF status is: ");
  •         Serial.println(TOF_status ,DEC);
  •  
  •         TOF_signal = TOF_data[j+12] | TOF_data[j+13]<<8;
  •         Serial.print("TOF signal is: ");
  •         Serial.println(TOF_signal ,DEC);
  •  
  •         Serial.println("");
  •       
  •      }
  •      break;
  •    }
  •  }

  •  
  • }


  •  
  • }

    Для исключения получения результата я его изменил, но надо его перепроверить, хотя результат я получаю стабильнее.

  • void requestEvent() {
  •  
  •  int story=0;
  •  for(int z=0;z<6;z++){
  •    Serial.print("available-");
  •    Serial.println(z);
  •   if (uart2.available()>=32) {
  •      BOT:
  •      for(int i=0;i<32;i++)
  •      {
  •      TOF_data[i] = uart2.read();
  •      }
  •     
  •      for(int j=0;j<16;j++)
  •      {
  •       
  •       // Serial.print("j");
  •       // Serial.print(j);
  •        if( (TOF_data[j]==TOF_header[0] && TOF_data[j+1]==TOF_header[1] && TOF_data[j+2]==TOF_header[2]) && (verifyCheckSum(&TOF_data[j],TOF_length)))
  •        {
  •          if(((TOF_data[j+12]) | (TOF_data[j+13]<<8) )==0)
  •          {
  •          Serial.println("Out of range!");
  •          }else{
  •         
  •   
  •          TOF_distance = (TOF_data[j+8]) | (TOF_data[j+9]<<8) | (TOF_data[j+10]<<16);
  •         
  •          TOF_story = TOF_distance;
  •         
  •          Serial.println("");
  •       
  •          }
  •          break;
  •        }
  •        if (j>14) {// надо проверить для чего я это прописал. задача в том, чтобы при отсутствие результата замера повторить его и получить результат
  •          story ++;
  •          //Serial.print("story");
  •          //Serial.println(story);
  •         
  •          if (story > 10) {
  •            TOF_distance = TOF_story ;
  •            break;
  •          }
  •          goto BOT;
  •          }
  •       
  •      }
  •    }
  •    if (TOF_distance>=1){
  •       
  •      break;
  •    }
  •  }
  •  loop:
  •  Wire.write('2'); // передаем 2 для подтверждения
  •  delay(50);
  •  Serial.print("TOF distance is: ");
  •  Serial.print(TOF_distance,DEC);
  •  Serial.println("mm");
  •  art1.write(TOF_distance & 0xFF); // передаем младший байт числа val
  •  art1.write((TOF_distance>>8) & 0xFF); // передаем старший байт числа val
  •  Serial.println(".");
  • }  
     

    Скорее всего код надо изменить следующим образом, т.к. он вызывается из void setup() {

  • void requestEvent() {
  •  
  •   for(int z=0;z<5;z++) //цикл для повтора если не получилось провести замер
  •    {
  •      // read from port 1:
  •      if (Serial1.available()>=32) {
  •        for(int i=0;i<32;i++)
  •        {
  •          TOF_data[i] = Serial1.read();
  •        }
  •     
  •        for(int j=0;j<16;j++)
  •        {
  •          if( (TOF_data[j]==TOF_header[0] && TOF_data[j+1]==TOF_header[1] && TOF_data[j+2]==TOF_header[2]) && (verifyCheckSum(&TOF_data[j],TOF_length)))
  •          {
  •            if(((TOF_data[j+12]) | (TOF_data[j+13]<<8) )==0)
  •            {
  •              TOF_distance = 555;
  •            }else{
  •             
  •       
  •              TOF_distance = (TOF_data[j+8]) | (TOF_data[j+9]<<8) | (TOF_data[j+10]<<16);
  •             
  •           
  •            }
  •            break;
  •          }
  •        }

  •  
  •      }
  •      if (TOF_distance >= 1){
  •        break; // выход из цикла z
  •      }
  •    }
  •  Wire.write('2'); // передаем 2 для подтверждения
  •  delay(50);
  •  Serial.print("TOF distance is: ");
  •  Serial.print(TOF_distance,DEC);
  •  Serial.println("mm");
  •  art1.write(TOF_distance & 0xFF); // передаем младший байт числа val
  •  art1.write((TOF_distance>>8) & 0xFF); // передаем старший байт числа val
  •  Serial.println(".");
  • }
  •  
     
Категория: Датчики / Добавил: zabariap /
/ Просмотры: 7/ Просмотры за сегодня:
Комментарии

Нет комментариев

Форма добавления комментария доступна только авторизованному пользователю.
Категории

Ключевые слова
Последние комментарии в разделе Arduino
  • Комментариев нет.