Аппаратура радиоуправления на Atmega328, STM32 и nRF24l01

Велимир
Offline
Зарегистрирован: 29.04.2017

Здравствуйте, захотелось создать "мощную" аппаратуру. Взял Arduino pro mini, припаял на макетку, джойстики и потенциометры, радиомодуль. Прослушал каналы, для поиска незашумлённого. Скачал библиотеку написал скетч... 

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

#include <SPI.h>

RF24 radio(9, 10);    //(CE, CSN)

int data[14];

void setup() 
{
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setAutoAck(0);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток) в ответ на входящий сигнал
  radio.setPayloadSize(28);     //размер пакета, в байтах
  radio.setChannel(120);         // канал
  radio.openWritingPipe(0xAABBCCDD11LL);  //труба
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp(); //начать работу
  radio.stopListening();  //не слушаем радиоэфир, мы передатчик
}
void loop () 
{
  data[0] = analogRead(A7);     //1 стик газ
  data[1] = map(analogRead(A6), 0, 1023, 1023, 0); //1 стик поворот 
  data[2] = map(analogRead(A4), 0, 1023, 1023, 0); //2 стик газ
  data[3] = analogRead(A5);  //2 стик поворот
  data[4] = map(analogRead(A0), 0, 1023, 1023, 0); // 1 потенциометр
  data[5] = map(analogRead(A0), 0, 1023, 1023, 0); // 2 потенциометр
  data[6] = map(analogRead(A0), 0, 1023, 1023, 0); // 3 потенциометр
  data[7] = map(analogRead(A0), 0, 1023, 1023, 0); // 4 потенциометр
  data[8] = map(digitalRead(3), 0, 1, 1, 0); //1 кнопка
  data[9] = map(digitalRead(2), 0, 1, 1, 0); //2 кнопка
  data[10] = digitalRead(4); //3 кнопка
  data[11] = digitalRead(5); //4 кнопка
  data[12] = digitalRead(6); //5 кнопка
  data[13] = digitalRead(7); //6 кнопка

  if(radio.write(&data, sizeof(data)))  digitalWrite(8, LOW);
  else digitalWrite(8, HIGH); 
    delay(1);
}

Теперь приёмник. Так пятка у меня зачесалась и взял я STM32F103C.

Всё припаял. Вот так соединил с радиомодулем:

PA5  - SCK
PA6  - MISO
PA7  - MOSI
PС14 - CE
PС15 - CSN
Скачал драйвера для STM, чтоб в Arduino IDE работать можно было. Нашёл переделанную библиотеку для модуля. Вот скетч:
#include <nRF24L01-STM.h>
#include <RF24-STM.h>
#include <RF24-STM_config.h>

#include <SPI.h>

RF24 radio(PC14, PC15);         //(CE, CSN)

int data[14];

void setup()
{
  Serial.begin(9600);
  radio.begin(); //активировать модуль
  radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)
  radio.setPayloadSize(28);     //размер пакета, в байтах
  radio.setChannel(120);  //выбираем канал (в котором нет шумов!)
  radio.openWritingPipe(0xAABBCCDD11LL);
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp(); //начать работу
  radio.startListening();
}

void loop() 
{
  if(radio.available())
  {
    radio.read(&data, sizeof(data)); // чтение данных
    Serial.print("data: "); // вывод заголовка в монитор
    Serial.println(data[0]);
  }
}

Открываю монитор порта, а там только "0", а должно быть 512, т.к. это показания со стика.

Подскажите, что не так.

P.s. Стабилизаторы на 3.3в припаяны, как и кондёры. В качестве пайки я уверен.

 

Велимир
Offline
Зарегистрирован: 29.04.2017

Велимир пишет:

 radio.openWritingPipe(0xAABBCCDD11LL);

Нашёл у себя ошибку в скетче приёмника. Эту строчку надо заменить на radio.openReadingPipe(1, 0xAABBCCDD11LL). Я заменил, но проблема таже.

 

b707
Offline
Зарегистрирован: 26.05.2017

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

А на приемнике? Функция radio.printDetails(); что у вас на STM выдает? - включите ее и на приемнике и на передатчике и добейтесь, чтоб все параметры в выдаче совпадали.

Велимир
Offline
Зарегистрирован: 29.04.2017

Я упростил код для теста 

TX:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

#include <SPI.h>

RF24 radio(9, 10);    //(CE, CSN)

void setup() 
{
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setAutoAck(0);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток) в ответ на входящий сигнал
  radio.setChannel(120);
  radio.openWritingPipe(0xAABBCCDD11LL); 
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp(); //начать работу
}
void loop () 
{
  byte data = 12;
  radio.write(&data, 1);
  delay(1000);
}

RX:

include <SPI.h>
#include <nRF24L01-STM.h>
#include <RF24-STM.h>
#include <RF24-STM_config.h>

RF24 radio(PC14, PC15);

byte data;

void setup()
{  
  Serial.begin(9600);
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток) в ответ на входящий сигнал
  radio.setChannel(120);
  radio.openReadingPipe(1, 0xAABBCCDD11LL); 
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp(); //начать работу
  radio.startListening();
}

void loop() 
{
  if(radio.available())
  {
    radio.read(&data, 1);
    Serial.println(data);
    delay(100);
  }
}

Теперь не выводит ничего.

Подскажите, пожалуйста, что не так.

b707
Offline
Зарегистрирован: 26.05.2017

Велимир пишет:

Теперь не выводит ничего.

Подскажите, пожалуйста, что не так.

Повторюсь, в первую очередь надо проверить, работает ли вообще NRF на STM24 - правильное ли подключение, рабочие ли библиотеки. Вставьте в скетч приемника функцию radio.printDetails(); между 21 и 22 строкой и убедитесь, что она выдает не нулевые значения.

Велимир
Offline
Зарегистрирован: 29.04.2017

Спасибо, попробую.

Велимир
Offline
Зарегистрирован: 29.04.2017

Сделал так и в передатчике, и в приёмнике. На удивление, в приёмнике работает, а в передатчике - нет. С чем это может быть связано?

b707
Offline
Зарегистрирован: 26.05.2017

Велимир пишет:

Сделал так и в передатчике, и в приёмнике. На удивление, в приёмнике работает, а в передатчике - нет. С чем это может быть связано?

Выражайтесь конкретнее - что именно вы сделали и что не работает?

Велимир
Offline
Зарегистрирован: 29.04.2017

Добавил radio.printDetails (); в приемник и в передатчик, в передатчик также добал Serial.begin(9600);. Приёмник выводит все настройки корректно, а передатчик ничего не выводит.

Велимир
Offline
Зарегистрирован: 29.04.2017

Я поставил в передатчике мощность HIGH, вместо MAX. И... всё заработало. На экране появились цифры "12".

Велимир
Offline
Зарегистрирован: 29.04.2017

Теперь нужно передать массив.

Велимир
Offline
Зарегистрирован: 29.04.2017

Всё работает! Спасибо за подсказку. Хороший я себе подарок на 14-ти летие сделал.

Вот код:

TX:

#include <nRF24L01.h>
#include <RF24.h>

#include <SPI.h>

RF24 radio(9, 10);    //(CE, CSN)
byte data[14];

void setup() 
{
  Serial.begin(9600);
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setChannel(120);
  radio.openWritingPipe(0xAABBCCDD11LL); 
  radio.setPALevel (RF24_PA_HIGH); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp();
}
void loop () 
{
  data[0] = map(analogRead(A7), 0, 1023, 0, 255);
  data[1] = map(analogRead(A6), 0, 1023, 255, 0);
  data[2] = map(analogRead(A4), 0, 1023, 255, 0);
  data[3] = map(analogRead(A5), 0, 1023, 0, 255);
  data[4] = map(analogRead(A0), 0, 1023, 255, 0);
  data[5] = map(analogRead(A1), 0, 1023, 255, 0);
  data[6] = map(analogRead(A2), 0, 1023, 255, 0);
  data[7] = map(analogRead(A3), 0, 1023, 255, 0);
  data[8] = map(digitalRead(3), 0, 1, 1, 0);
  data[9] = map(digitalRead(2), 0, 1, 1, 0);
  data[10] = digitalRead(4);
  data[11] = digitalRead(5);
  data[12] = digitalRead(6);
  data[13] = digitalRead(7);

  delay(10);
  
  if(radio.write(&data, sizeof(data)))
  {
    digitalWrite(8, LOW);
  }
  else digitalWrite(8, HIGH); 
}

RX:

#include <nRF24L01-STM.h>
#include <RF24-STM.h>
#include <SPI.h>

RF24 radio(PC14, PC15);         //(CE, CSN)

byte data[14];

void setup()
{
  Serial.begin(9600);
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток) в ответ на входящий сигнал
  radio.setChannel(120);
  radio.openReadingPipe(1, 0xAABBCCDD11LL); 
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp();
  radio.startListening();
}

void loop() 
{
  if(radio.available())
  {
    radio.read(&data, sizeof(data)); // чтение данных
    Serial.print("data[0]: ");
    Serial.println(data[0]);
    Serial.print("data[1]: ");
    Serial.println(data[1]);
    Serial.print("data[2]: ");
    Serial.println(data[2]);
    Serial.print("data[3]: ");
    Serial.println(data[3]);
    Serial.print("data[4]: ");
    Serial.println(data[4]);
    Serial.print("data[5]: ");
    Serial.println(data[5]);
    Serial.print("data[6]: ");
    Serial.println(data[6]);
    Serial.print("data[7]: ");
    Serial.println(data[7]);
    Serial.print("data[8]: ");
    Serial.println(data[8]);
    Serial.print("data[9]: ");
    Serial.println(data[9]);
    Serial.print("data[10]: ");
    Serial.println(data[10]);
    Serial.print("data[11]: ");
    Serial.println(data[11]);
    Serial.print("data[12]: ");
    Serial.println(data[12]);
    Serial.print("data[13]: ");
    Serial.println(data[13]);
    Serial.println();
    delay(3000);
  }
}

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

b707
Offline
Зарегистрирован: 26.05.2017

теперь к 15-ти годам выучи циклы, а то в приемнике код совершено жуткий. Тридцать с лишним одинаковых строк начиная с 19-й можно заменить тремя.

Велимир
Offline
Зарегистрирован: 29.04.2017

Думаю, вы имели в виду это:

#include <nRF24L01-STM.h>
#include <RF24-STM.h>
#include <SPI.h>

RF24 radio(PC14, PC15);

byte data[14];

void setup()
{
  Serial.begin(9600);
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток) в ответ на входящий сигнал
  radio.setChannel(120);
  radio.openReadingPipe(1, 0xAABBCCDD11LL); 
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp();
  radio.startListening();
}

void loop() 
{
  if(radio.available())
  {
    radio.read(&data, sizeof(data)); // чтение данных
    for(byte x = 0; x < 14; x++)
    {
      Serial.print("data[");
      Serial.print(x);
      Serial.print("]:");
      Serial.print(data[x]);
      Serial.println();     
    }
    delay(3000);
  }
}

 

Велимир
Offline
Зарегистрирован: 29.04.2017
b707
Offline
Зарегистрирован: 26.05.2017

Велимир пишет:

Думаю, вы имели в виду это:

#include <nRF24L01-STM.h>
#include <RF24-STM.h>
#include <SPI.h>

RF24 radio(PC14, PC15);

byte data[14];

void setup()
{
  Serial.begin(9600);
  radio.begin(); //активировать модуль
  delay(1000);
  radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток) в ответ на входящий сигнал
  radio.setChannel(120);
  radio.openReadingPipe(1, 0xAABBCCDD11LL); 
  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  radio.powerUp();
  radio.startListening();
}

void loop() 
{
  if(radio.available())
  {
    radio.read(&data, sizeof(data)); // чтение данных
    for(byte x = 0; x < 14; x++)
    {
      Serial.print("data[");
      Serial.print(x);
      Serial.print("]:");
      Serial.print(data[x]);
      Serial.println();     
    }
    delay(3000);
  }
}

 

неплохо. 35-ю строчку тоже можно выкинуть

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Хороший задел для 14-летия )))

Велимир
Offline
Зарегистрирован: 29.04.2017

Так он всё в одну строчку будет писать. Неудобно.

b707
Offline
Зарегистрирован: 26.05.2017

Велимир пишет:

Так он всё в одну строчку будет писать. Неудобно.

в 34 строке напишите println

Велимир
Offline
Зарегистрирован: 29.04.2017

А, ну да. Жаль, что через пару дней уезжаю в "Мухосранск" и придётся приостановить проектную деятельность.