Пожалуйста, помогите переделать скетч.

Тема в разделе "Arduino & Shields", создана пользователем Женя., 9 июл 2017.

  1. Женя.

    Женя. Нуб

    Доброго времени суток. Пожалуйста, помогите переделать скетч. Счас он работает так, на передатчике: Кнопка, потенциометр, движковый резистjр.
    На приёмнике: Реле, сервопривод, лента светодиодов.
    А мне нужно, на передатчике: Два потенциометра.
    На приёмнике: Два сервопривода.
    Мне понравился именно этот скетч тем, что он передаёт данные не постоянно, а только тогда, когда данные посылаются. То есть к примеру, я крутнул потенциометр, nRF24L01 данные отправила, и отключилась.
    Передатчик:
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"

    RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
    //RF24 radio(9,53); // для Меги

    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    byte button = 3;  // кнопка на 3 цифровом
    byte potent = 0; // потенциометр на 0 аналоговом
    byte slider = 1; // движковый потенциометр на 1 аналоговом пине

    byte transmit_data[3]; // массив, хранящий передаваемые данные
    byte latest_data[3]; // массив, хранящий последние переданные данные
    boolean flag; // флажок отправки данных

    void setup() {
      Serial.begin(9600); //открываем порт для связи с ПК

      pinMode(button, INPUT_PULLUP); // настроить пин кнопки

      radio.begin(); //активировать модуль
      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)
      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал
      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openWritingPipe(address[0]);   //мы - труба 0, открываем канал для передачи данных
      radio.setChannel(0x60);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
      //должна быть одинакова на приёмнике и передатчике!
      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу
      radio.stopListening();  //не слушаем радиоэфир, мы передатчик
    }

    void loop() {

      transmit_data[0] = !digitalRead(button); // инвертированный (!) сигнал с кнопки
      transmit_data[1] = map(analogRead(potent), 0, 1023, 0, 180); // получить значение
      // в диапазоне 0..1023, перевести в 0..180, и записать на 1 место в массиве
      transmit_data[2] = map(analogRead(slider), 0, 1023, 0, 255);

      for (int i = 0; i < 3; i++) { // в цикле от 0 до числа каналов
        if (transmit_data[i] != latest_data[i]) { // если есть изменения в transmit_data
          flag = 1; // поднять флаг отправки по радио
          latest_data[i] = transmit_data[i]; // запомнить последнее изменение
        }
      }

      if (flag == 1) {
        radio.powerUp(); // включить передатчик
        radio.write(&transmit_data, sizeof(transmit_data)); // отправить по радио
        flag = 0; //опустить флаг
        radio.powerDown(); // выключить передатчик
      }

    }
    Приёмник:
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include <Servo.h>

    RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
    //RF24 radio(9,53); // для Меги

    byte recieved_data[3]; // массив принятых данных
    byte relay = 2; // реле на 2 цифровом
    byte servo = 3; // сервопривод на 3 цифровом
    byte mosfet = 5; // мосфет на 5 цифровом (ТУТ ЕСТЬ ШИМ!!!)

    Servo myservo;

    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    void setup() {
      Serial.begin(9600); //открываем порт для связи с ПК

      pinMode(relay, OUTPUT); // настроить пин реле как выход
      pinMode(mosfet, OUTPUT); // настроить пин мосфета как выход

      myservo.attach(servo);

      radio.begin(); //активировать модуль
      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)
      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал
      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openReadingPipe(1, address[0]);     //хотим слушать трубу 0
      radio.setChannel(0x60);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
      //должна быть одинакова на приёмнике и передатчике!
      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу
      radio.startListening();  //начинаем слушать эфир, мы приёмный модуль
    }

    void loop() {
      byte pipeNo;
      while ( radio.available(&pipeNo)) {  // слушаем эфир со всех труб
        radio.read( &recieved_data, sizeof(recieved_data) );         // чиатем входящий сигнал
        digitalWrite(relay, recieved_data[0]); // подать на реле сигнал с 0 места массива
        //то бишь 0 или 1
        myservo.write(recieved_data[1]); // повернуть серво на угол 0..180
        // значение получено с 1 элемента массива
        analogWrite(mosfet, recieved_data[2]); // подать на мосфет ШИМ сигнал
        // в соответствии с принятыми данными со 2 места массива, диапазон 0...255
      }
    }
     
     
  2. vvr

    vvr Инженерище

    а по аналогии сделать не пробовали?
     
  3. Женя.

    Женя. Нуб

    Пробовал, не получилось(
    Но спаял правильно. Я проверял на тестовом скетче, цифры в мониторе бежали и на приёмнике и на передатчике.
     
  4. vvr

    vvr Инженерище

    у вас же есть уже потенциометр
    вот по аналогии пропишите ещё один
     
  5. Женя.

    Женя. Нуб

    Так я прописывал, но видна моих знаний не хватает..
    Код (C++):
    Передатчик:

    #include <SPI.h>

    #include "nRF24L01.h"

    #include "RF24.h"

    RF24 radio(9, 10); //

    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    byte potent0 = 0; // потенциометр на 0 аналоговом

    byte potent1 = 1; //


    byte transmit_data[2]; // массив, хранящий передаваемые данные

    byte latest_data[2]; // массив, хранящий последние переданные данные

    boolean flag; // флажок отправки данных

    void setup() {

      Serial.begin(9600); //открываем порт для связи с ПК

      radio.begin(); //активировать модуль

      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл

      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)

      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал

      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openWritingPipe(address[0]);   //мы - труба 0, открываем канал для передачи данных

      radio.setChannel(0x5f);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_LOW); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX

      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS

      //должна быть одинакова на приёмнике и передатчике!

      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу

      radio.stopListening();  //не слушаем радиоэфир, мы передатчик

    }

    void loop() {

        transmit_data[1] = map(analogRead(potent1), 0, 1023, 0, 180); // получить значение

      // в диапазоне 0..1023, перевести в 0..180, и записать на 1 место в массиве

        transmit_data[0] = map(analogRead(potent0), 0, 1023, 0, 180);

      for (int i = 0; i < 3; i++) { // в цикле от 0 до числа каналов

        if (transmit_data[i] != latest_data[i]) { // если есть изменения в transmit_data

          flag = 1; // поднять флаг отправки по радио

          latest_data[i] = transmit_data[i]; // запомнить последнее изменение

        }

      }

      if (flag == 1) {

        radio.powerUp(); // включить передатчик

        radio.write(&transmit_data, sizeof(transmit_data)); // отправить по радио

        flag = 0; //опустить флаг

        radio.powerDown(); // выключить передатчик

      }

    }
    Приёмник:

    #include <SPI.h>

    #include "nRF24L01.h"

    #include "RF24.h"

    #include <Servo.h>

    RF24 radio(9, 10); //

    byte recieved_data[2]; // массив принятых данных

    byte servo = 3; // сервопривод на 3 цифровом

    byte servo2 = 5; //

    Servo myservo;

    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    void setup() {

      Serial.begin(9600); //открываем порт для связи с ПК

      myservo.attach(servo);

      myservo.attach(servo2);

      radio.begin(); //активировать модуль

      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл

      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)

      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал

      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openReadingPipe(1, address[0]);     //хотим слушать трубу 0

      radio.setChannel(0x5f);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_LOW); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX

      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS

      //должна быть одинакова на приёмнике и передатчике!

      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу

      radio.startListening();  //начинаем слушать эфир, мы приёмный модуль

    }

    void loop() {

      byte pipeNo;

      while ( radio.available(&pipeNo)) {  // слушаем эфир со всех труб

        radio.read( &recieved_data, sizeof(recieved_data) );         // чиатем входящий сигнал

        //то бишь 0 или 1

        myservo.write(recieved_data[1]); // повернуть серво на угол 0..180

        // значение получено с 1 элемента массива

        myservo.write(recieved_data[2]); // подать на мосфет ШИМ сигнал

        // в соответствии с принятыми данными со 2 места массива, диапазон 0...180

      }

    }
     
     
  6. vvr

    vvr Инженерище

    передатчик
    for (int i = 0; i < 3; i++) { // в цикле от 0 до числа каналов
    заменить
    for (int i = 0; i < 2; i++) { // в цикле от 0 до числа каналов

    приёмник
    myservo.write(recieved_data[2]); // подать на мосфет ШИМ сигнал
    заменить
    myservo.write(recieved_data[0]); // подать на мосфет ШИМ сигнал
     
    Женя. нравится это.
  7. Женя.

    Женя. Нуб

    Одна серва работает, вторая нет.
     
  8. vvr

    vvr Инженерище

    весь код всегда показывайте
     
  9. Женя.

    Женя. Нуб

    Передатчик:
    Код (C++):
    #include <SPI.h>

    #include "nRF24L01.h"

    #include "RF24.h"

    RF24 radio(9, 10); //

    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    byte potent0 = 0; // потенциометр на 0 аналоговом

    byte potent1 = 1; //


    byte transmit_data[2]; // массив, хранящий передаваемые данные

    byte latest_data[2]; // массив, хранящий последние переданные данные

    boolean flag; // флажок отправки данных

    void setup() {

      Serial.begin(9600); //открываем порт для связи с ПК

      radio.begin(); //активировать модуль

      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл

      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)

      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал

      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openWritingPipe(address[0]);   //мы - труба 0, открываем канал для передачи данных

      radio.setChannel(0x5f);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_LOW); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX

      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS

      //должна быть одинакова на приёмнике и передатчике!

      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу

      radio.stopListening();  //не слушаем радиоэфир, мы передатчик

    }

    void loop() {

        transmit_data[1] = map(analogRead(potent1), 0, 1023, 0, 180); // получить значение

      // в диапазоне 0..1023, перевести в 0..180, и записать на 1 место в массиве

        transmit_data[0] = map(analogRead(potent0), 0, 1023, 0, 180);

      for (int i = 0; i < 2; i++) { // в цикле от 0 до числа каналов

        if (transmit_data[i] != latest_data[i]) { // если есть изменения в transmit_data

          flag = 1; // поднять флаг отправки по радио

          latest_data[i] = transmit_data[i]; // запомнить последнее изменение

        }

      }

      if (flag == 1) {

        radio.powerUp(); // включить передатчик

        radio.write(&transmit_data, sizeof(transmit_data)); // отправить по радио

        flag = 0; //опустить флаг

        radio.powerDown(); // выключить передатчик

      }

    }
    Приёмник:
    Код (C++):
    #include <SPI.h>

    #include "nRF24L01.h"

    #include "RF24.h"

    #include <Servo.h>

    RF24 radio(9, 10); //

    byte recieved_data[2]; // массив принятых данных

    byte servo = 3; // сервопривод на 3 цифровом

    byte servo2 = 5; //

    Servo myservo;

    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    void setup() {

      Serial.begin(9600); //открываем порт для связи с ПК

      myservo.attach(servo);

      myservo.attach(servo2);

      radio.begin(); //активировать модуль

      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл

      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)

      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал

      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openReadingPipe(1, address[0]);     //хотим слушать трубу 0

      radio.setChannel(0x5f);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_LOW); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX

      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS

      //должна быть одинакова на приёмнике и передатчике!

      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу

      radio.startListening();  //начинаем слушать эфир, мы приёмный модуль

    }

    void loop() {

      byte pipeNo;

      while ( radio.available(&pipeNo)) {  // слушаем эфир со всех труб

        radio.read( &recieved_data, sizeof(recieved_data) );         // чиатем входящий сигнал

        //то бишь 0 или 1

        myservo.write(recieved_data[1]); // повернуть серво на угол 0..180

        // значение получено с 1 элемента массива

        myservo.write(recieved_data[0]); // подать на мосфет ШИМ сигнал

        // в соответствии с принятыми данными со 2 места массива, диапазон 0...180

      }

    }
     
  10. vvr

    vvr Инженерище

    в приёмнике не объявили вторую серву

    Servo myservo1;
    Servo myservo2;

    в сетапе

    myservo1.attach(servo);
    myservo2.attach(servo2);

    в лупе

    myservo1.write(recieved_data[1]);
    myservo2.write(recieved_data[0]);
     
    Женя. нравится это.
  11. Женя.

    Женя. Нуб

    О! Заработала вторая серва! Спасибо!!! )
     
  12. vvr

    vvr Инженерище

    удачи))))
     
    Женя. нравится это.
  13. NikitOS

    NikitOS Король шутов Администратор

    Как хорошо разобрались))
     
    Женя. нравится это.
  14. Tomasina

    Tomasina Сушитель лампочек Модератор

    Всегда бы так вопросы задавали.
    И вопрос осмысленный, и код оформлен, и даже самостоятельно попытался разобраться.
     
    Женя. и NikitOS нравится это.
  15. NikitOS

    NikitOS Король шутов Администратор

    Вы правы;)
     
    Женя. нравится это.
  16. Женя.

    Женя. Нуб

    Спасибо большое! ) А ещё вопрос, сервы (SG90) поворачиваются, но как то дёргано, примерно по градусов 5 за один рывок. (Я планировал использовать их как поворотное устройство для видеокамеры.) Можно ли исправить дёрганье программно? Или может быть дело в этих сервах? Они аналоговые, может нужно использовать цифровые?
     
  17. vvr

    vvr Инженерище

    если вы собираетесь во время движения сервы снимать видео да ещё с хорошей картинкой то они вообще для этого не подходят, ни цифровые ни аналоговые.
    для фокуса - зума да
    мотор-редуктор даёт самое плавное движение
    шаговик при режиме микрошага 128
    пробовал при 32 - всё равно дёрганья заметны, нужно обрабатывать стабилизатором
     
    Женя. нравится это.
  18. Женя.

    Женя. Нуб

    Нет, снимать не собираюсь, буду использовать как камеру видеонаблюдения с зумом. А какой мотор-редуктор Вы посоветуете?
     
  19. vvr

    vvr Инженерище

    ну тогда смело берите MG996.
    только правильно запитайте серву - отдельный источник питания 5-6 вольт 1 ампер и общая земля с дуней
     
    Женя. нравится это.
  20. Женя.

    Женя. Нуб

    Спасибо!
    А ещё, подскажите пожалуйста, как правильно прописать команду detach, что бы сервы отключались когда на них не подаются команды. А то они иногда дребезжат, и при этом вибрируют.