Совместная работа 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() {
  •  
  •   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(".");
  • }  
     
Категория: Датчики / Добавил: zabariap /
/ Просмотры: 5/ Просмотры за сегодня:
Комментарии

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

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

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