Соединение двух Arduino Uno по SPI...

Тема в разделе "Проводная и беспроводная связь", создана пользователем matwaysha, 2 май 2019.

  1. Belkin

    Belkin Гик

    Так точно, сам уже схему разглядел только что... ;)
    Только FT232 и подобных там не увидел... ;)
     
  2. Daniil

    Daniil Гуру

    Маленький успех)
    но если вы пойдете аккуратно с отладкой как мы вам советуем, то по пути вы ещё и разберетесь. Как и почему работает этот протокол.
    Подумав, я понимаю, что параллельный интерфейс и правда прост, но юарт привычен)
     
  3. Daniil

    Daniil Гуру

    про ft и им подобных это на случай китацев.
     
  4. Belkin

    Belkin Гик

    Последовательный требует предварительных настроек параметров...
    Не исключены ошибки при передаче, требуется контроль...

    Параллельный же сложнее только технологически (требует большего кол-ва соединений), зато прост в обращении:
    - выставил в порт байт
    - "топнул" пином
    - принимающий увидел "топ" (удобно использовать прерывание), прочитал байт
    - передающий повторяет п.1 и 2 столько, сколько надо, принимающему остается только "по полочкам разложить"...

    Скорость обмена - раза в 4-6 выше, чем у UARTa.
    Устойчивость к ошибкам - практически 100%, сводится только к умению программиста ;)
    Если хватает "ног" и устройства рядом, то я - за параллельный ! ;)
     
    Daniil нравится это.
  5. matwaysha

    matwaysha Нерд

    Устройство рядом, но ног, не хватает. Мне просто с головной нужно сигналы на сервоприводы отправлять, в этом проблема.
     
  6. matwaysha

    matwaysha Нерд

    Прям очень странно, но отправка данных не идет.
    Я это проверил просто монитором порта, в программе же Serial.print используется.
     
  7. matwaysha

    matwaysha Нерд

    Пишу Serial.print в само тело loop - передача идет (опять по экрану на компьютере), светодиоды мигают.
     
  8. Belkin

    Belkin Гик

    Формируйте алгоритм программы согласно хотелок.

    Правильнее будет крутиться в некоем главном цикле, а из него, по каким-либо командам вызывать соответствующие подпрограммы.
    Командами могут быть (например) внешние сигналы, внутренние или внешние прерывания, результаты расчетов...
     
  9. matwaysha

    matwaysha Нерд

    Так оно примерно так и работало. Был таймер, на нем прерывания с вызовом специально написанной функции, в которой всё тот же Serial.print/
     
  10. Daniil

    Daniil Гуру

    У меня ардуинка леонардо бредила когда я писал команды в одну строчку:
    сериал.принт("а"); сериал.принт("б");
    "б" не отсылалась(
    когда вы принт в луп помещаете таймер продолжает работать? Может, из-за него какие-то косяки?
     
    matwaysha нравится это.
  11. Belkin

    Belkin Гик

    Вы пытаетесь добомбить старую программу или таки начали сначала и поэтапно ? ;)
     
    matwaysha нравится это.
  12. matwaysha

    matwaysha Нерд

    Сейчас ещё проверил, не выводит специально написанный для этого метод... Но почему? - это вопрос.
    Вот он сам:
    Код (C++):
    void cout(){
      if(n == 1){
        Serial.print(":A");
        uint32_t tmp = (uint32_t)((x + 90)*1e3);
        Serial.print(tmp, HEX);
        Serial.print('\n');
        n = 2;
      return;
      }
       if(n == 2){
         Serial.print(":B");
        uint32_t tmp = (uint32_t)((y + 90)*1e3);
        Serial.print(tmp, HEX);
        Serial.print('\n');
        n = 1;
        return;
      }
    }
    по поводу таймера - он был выключен, когда принт в луп пихал, эта штука тоже без таймера проверялась просто в луп запихнута (x и y - float), по поводу порядка действий, именно систему вывода и приема уже несколько раз (имеется ввиду с начала) переписывал, а саму программу, которая делает все остальные действия - не трогал.
     
  13. Daniil

    Daniil Гуру

    Т.е. если написать все принты в лупе, то отправляет, а если через процедуру то нет?

    Про работу сериала и прерывания обсуждали проблему в гугле (по запросу "serial.print в прерывании") (не подумайте, что я вас посылаю, просто, ссылок (и на амперку) вылетело много и все интересные, а полноценный код мы не видели). Если в кратце, то serial и прерывания нужно программировать аккуратно.
     
  14. matwaysha

    matwaysha Нерд

    Да. Именно так. В лупе отправляет, а так нет. Посмотрю, про то, как это правильно делать.
    Но даже без прерываний, просто эта штука вызывается каждый раз в лупе (cout(); ), и всё - равно ничего не выводит.
     
  15. Belkin

    Belkin Гик

    А у вас для if(n == 1) значение n изменяется до вызова cout или только в этой подпрограмме ? ;)

    Просто после выполнения
    if(n == 1){
    .....
    n = 2; - меняем значение
    return; - ... и выходим из cout даже не проверив, что if(n == 2)...

    Если я правильно понимаю СИ-шные конструкции... ;)
    Я пишу в Bascom, но от этого принципы программирования не меняются... ;)
     
  16. matwaysha

    matwaysha Нерд

    Идея была да такая, чтобы через раз выводить то один угол то второй, я угол вывел, номер следующего выводимого угла поменял, и вызвал return, чтобы не проверять второе условие (мне нужно, чтоб он второй угол отправил в след. раз, а не сейчас), что - то мне кажется, что проблема в return, но убрать его и вместо него написать n = 1, чтобы выводился только первый угол ничего не дало. всё - равно ничего не выводится.
     
  17. Belkin

    Belkin Гик

    Присваивайте значение n, а затем вызывайте cout.
    При n = 1 выполнится условие if(n == 1), а при n = 2 соответственно if(n == 2) и return не нужен будет в обоих условиях.
    Так же лишними будут n = ...
     
  18. matwaysha

    matwaysha Нерд

    сделал вот так:
    Код (C++):
     n = (n % 2) + 1;
                cout();
    Код (C++):
    void cout(){
      if(n == 1){
        Serial.print(":A");
        uint32_t tmp = (uint32_t)((x + 90)*1e3);
        Serial.print(tmp, HEX);
        Serial.print('\n');
      }
       if(n == 2){
         Serial.print(":B");
        uint32_t tmp = (uint32_t)((y + 90)*1e3);
        Serial.print(tmp, HEX);
        Serial.print('\n');
      }
    }
    передача пошла, причем, походу того, что надо, вот скрин того, что пришло:
    upload_2019-5-4_14-3-13.png
    Но при подключении к принимающему устройству - светодиод на прием не горел, никаких изменений на экране. Значит теперь одной проблемой меньше, но не понятно, почему приемник вообще ничего не принимает.
     
    Belkin нравится это.
  19. matwaysha

    matwaysha Нерд

    Теперь когда выделяю то, что пришло с передатчика и в этой программе отсылаю на приемник - он мигает светодиодом на прием, но на экране всё ещё нули.
     
  20. matwaysha

    matwaysha Нерд

    В программу добавил счетчик в SerialEvent в While;
    Код (C++):
    void serialEvent(){
      while(Serial.available()){
        char inChar = (char)Serial.read();
        inputString += inChar;
        if(inChar == '\n'){
          stringComplete = true;
        }
        k++;
      }
    }
    При отправке строк с той программы счетчик работает - данные приходят, и, наверное, записываются в строку, но на экране нули, значит ошибка где - то в той части, которая отвечает непосредственно за обработку пришедших данных. Вот она:
    Код (C++):
    if(stringComplete = true){
        for(int i = 0; i < inputString.length(); i++){
          if(inputString[i] == '\n'){
            indexEnd = i - 1;
          }
          if(inputString[i] == ':'){
            indexStart = i + 1;
          }
        }
       
        for(int i = indexStart + 1; i <= indexEnd; i++){
          tmp = inputString[i];
          if(i != indexEnd){
            tmp = tmp << 8;
          }
        }
        if(inputString[indexStart] == 'A'){
          x = (((float)tmp) - 90)/1e3;
        }
        else{
          y = (((float)tmp) - 90)/1e3;
        }
        tmp = 0;
      }