Передача 3-х значенй по блютус

Тема в разделе "Arduino & Shields", создана пользователем Smollwille, 25 фев 2018.

  1. Smollwille

    Smollwille Нуб

    Суть вопроса: на ардуино uno сделан пуль с джойстиком, на ардуино mega собран робот(4-х колесный, каждое колесо управляется отдельно), связь по блютус HC-05
    Надо передавать в каждый момент времени 2 значении или 3. В зависимости от положения джойстика направление движения по осям и скорость(скорость привязана к положению джойстика).

    Пульт:
    Весь код думаю нет смысла печатать, только часть где происходит передача.
    Тут только 2 вопроса какой тип даных использовать? int, char?
    char мне менее удобен т.к. он до 127, мне желательно чтоб 225 помещалось.
    И как правильно Serial.write или Serial.print?

    Код (C++):

    Serial.write(skorost_x);
    Serial.write(skorost_y);
    Serial.write(napreavleniey);
    delay (10);
    }
    Робот: Роботу надо принять 3 значения и записать их в массив. Вот тут у меня сложности
    Код (C++):

    char x[2];
    char idx = 0;
    .....
    .....
    .....
    void loop()
    {
        if ( (idx < 2) && (Serial.available() > 0) ) {

      x[idx++] = Serial.read();
      }
      if (idx == 2) {
    skorost_x=x[1];
    skorost_y=x[2];
    napreavleniey=x[3;]
     
    Пробовал по разному, чото получалось принять, робот начинал хаотично дергаться. Это максимум что удалось. Не совсем уверен что правильно записываю в массив.
    И не понимаю как объяснить на программном уровне в какой момент начинать принимать данные, и что пришедшие число это скорость по оси х и это первый элемент массива, второй это скорость по оси y и это второй элемент массива.
     
  2. примеров в сети уйма
     
  3. mcureenab

    mcureenab Гуру

    Код (C++):
    Serial.write(skorost_x);
    Serial.write(skorost_y);
    Serial.write(napreavleniey);
    Здесь не маркера начала пакета данных. В потоке байтов робот может пропустить байт и потерять порядок их следования.
     
    b707 нравится это.
  4. Smollwille

    Smollwille Нуб

    Ткните носом в пример. Пример долго гуглил, но так и не смог найти в основном примеры как к сотового одно значение передавать
     
  5. Smollwille

    Smollwille Нуб

    Маркер делал, но с ним вообще нечего не работает, не знаю как принять это маркер
     
  6. issaom

    issaom Гуру

    Если вы не знаете чем Serial.write отличается от Serial.print то Вам рано делать такие проекты - ищите готовый код в сети и пытайтесь переписать под себя. А если по теме:
    Делаете пакет в байтах фиксированной длины (2 или 3 не катят если нужно передавать разное - сделайте пакет 2+3=5 байт)
    Каждые 250ms (не важно нажимали кнопки или нет)
    шлете с передатчика массив Byte из 3х БАЙТ информации
    Serial.write(Sendbute, 3)
    На приемнике в цикле принимаете сразу ВЕСЬ массив командой
    Serial.readBytes(Sendbute, 3)
    /в сеттапе Serial.setTimeout(300)/
    Serial.readBytes вернет вам количество принятых байт (если оно меньше трех ни каких команд
    не выполняете) а если получили три значит вы получили то что нужно и именно в той последовательности.
    (рекомендую прочитать от корки до корки описание всех функций http://doc.arduino.ua/ru/prog/Serial)
    (естественно ни каких длинных задержек в скетчах быть не должно)
    Есть еще 2 варианта реализации: это мутить протокол на ascii символах или использовать 9 битный пакет передачи данных по UART но для р/у игрушек это перебор. Проще всего реализовать на временных интервалах используя посылки стандартной длины. Если за отведенное время ничего не пришло или пришло не все ни каких действий не выполняем. Если за отведенное время пришел пакет заданной длинны то пришло именно то что нужно. /заодно обработаете потерю связи/ С задержками возможно придется поиграться.
     
  7. Smollwille

    Smollwille Нуб

  8. Smollwille

    Smollwille Нуб

    Спасибо! Примерно понятно, буду разбиратся
     
  9. Smollwille

    Smollwille Нуб

    Понимаю что что то однозначно неправильно. Только вот что?
    Передатчик
    Код (C++):
    char myArray[3];
    ........
    myArray[0]=224;
    myArray[1]=224;
    myArray[2]=505;
    Serial.write('a');
    Serial.write(myArray[2]);
    Применик
    Код (C++):
    char incomingBytes[10];
    char val1;
    char val2;
    char val3;
    void setup()

    {
    Serial.begin(9600);
    Serial1.begin(9600);
    }
    void loop()
    {
    if (Serial1.available() > 0 && char(Serial1.read()) == 'a')
    {
    Serial1.readBytes(incomingBytes, 9);

    val1=incomingBytes[0];
    val2=incomingBytes[1];
    val3=incomingBytes[2];


    if (val1==224)
    {
    Serial.println("yes");
    Serial.println(val1);
    }
    else
    {Serial.println("no");
    Serial.println(val1);
    Serial.println (val2);
    Serial.println (val3);
    }
    }
    }
    Данные приходят, но некорректные
    Если на применик тип даных byte то в мониторе порта вижу
    Код (C++):
    249
    97
    249
     
    если char
    Код (C++):
    щ
    а
    щ
    тут вроде как с ascii надо разбираться, по байтам данные не в десятично же системе приходят?
     
  10. mcureenab

    mcureenab Гуру

    249 = 505 - 256

    Просто в char не помещается число больше 255. От 505 остаются только младшие 8 бит из 9.
     
  11. Smollwille

    Smollwille Нуб

    Значений уменьшил, но все равно логики в полученных данных не вижу
    Часто проскакивает число 97, судя по кодировке ASCII это буква "а"
    Так же не уверен что записывать принятые значения в переменую типа byte правильно.
    И какой то косяк с записью в массив, явно что данные накладываются

    Код (C++):
    #include <Time.h>
    #include <TimeLib.h>
    #include <SoftwareSerial.h>
    char myArray[3];

    void setup()
    {
    BTSerial.begin(38400);
    Serial.begin(9600);
    }
    void loop()
    {
    myArray[0]=12;
    myArray[1]=88;
    myArray[2]=10;
    Serial.write('a');
    Serial.print(myArray[2]);
    delay (10);
    }
     
    Код (C++):
    byte incomingBytes[4];
    byte val1;
    byte  val2;
    byte  val3;
    byte  val4;
    byte val5;
    void setup()

    {
    Serial.begin(9600);
    Serial1.begin(9600);
    }
    void loop()
    {
    if (Serial1.available() > 0 && byte(Serial1.read()) == 'a')
    Serial.flush();
    {
    Serial1.readBytes(incomingBytes, 3);
    val1=incomingBytes[0];
    val2=incomingBytes[1];
    val3=incomingBytes[2];
    val4=incomingBytes[3];
    val4=incomingBytes[4];
     
    if (val1==12)
    {
    Serial.println("yes");
    Serial.println(val1);
    }
    else
    {
    Serial.println("no");
    Serial.print ("1= ");
    Serial.println(val1);
    Serial.print ("2= ");
    Serial.println(val2);
    Serial.print ("3= ");
    Serial.println (val3);
    Serial.print ("4= ");
    Serial.println (val4);
    Serial.print ("5= ");
    Serial.println (val5);


    incomingBytes[0]=0;
    incomingBytes[1]=0;
    incomingBytes[2]=0;
    incomingBytes[3]=0;
    //char incomingBytes[3]={0,0,0};
    }
    }
    }
    324.png
     
  12. b707

    b707 Гуру

    Smollwille, поправьте код, он у вас вставился неверно - непонятно что к чему.
    Во второй части кода у вас куча ошибок.
    Во-впервых, если масив incomingBytes имеет 4 элемента, то в нем не может быть элемента incomingBytes[4]
    Во-вторых, вы из Сериала читаете только три байта, а использовать из массива пытаетесь толи 4. толи даже пять.
    В третьих, у вас в процедуре loop() лишняя скобка.
    В четвертых - почитайте описание процедуры Serial.flush() - по-моему она делает совсем не то, что вы думаете.
    и так далее...

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