Nano виснет при получении сигнала через nrf

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

Доброго всем дня. 

Потихоньку пилю радиоуправление. Собрал прототип джойстика, 3 реостата и 3 двухпозиционных тумблера.

Массив в передатчике формирую так:

int transmit_data[13];          // массив пересылаемых данных

Тумблеры притянуты через внутренние резисторы

  pinMode(tggl_11, INPUT_PULLUP);
  pinMode(tggl_12, INPUT_PULLUP);
  pinMode(tggl_21, INPUT_PULLUP);
  pinMode(tggl_22, INPUT_PULLUP);
  pinMode(tggl_31, INPUT_PULLUP);
  pinMode(tggl_32, INPUT_PULLUP);

Заполнение массива производится путем опроса местного населения

  transmit_data[0] = map(analogRead(A1), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  transmit_data[1] = map(analogRead(A6), 0, 1023, 0, 255);
  transmit_data[2] = map(analogRead(A7), 0, 1023, 0, 255);
  transmit_data[3] = map(analogRead(A0), 0, 550, 0, 255);
  transmit_data[4]= map(analogRead(A2), 0, 1023, 0, 255);
  transmit_data[5]= digitalRead(tggl_11);
  transmit_data[6] = digitalRead(tggl_12);
  transmit_data[7] = digitalRead(tggl_21);
  transmit_data[8] = digitalRead(tggl_22);
  transmit_data[9] = digitalRead(tggl_31);
  transmit_data[10] = digitalRead(tggl_32);

В приемнике на текущий момент никакой переферии нет. ТОлько NANO и NRF24l01

Принимаемые данные:

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

Вывожу все это дело на печать

  Serial.print ("J1 X ");
  Serial.print (recieved_data[0]);
  Serial.print (" J1 Y "); 
  Serial.print (recieved_data[1]);
  Serial.print (" J2 X ");
  Serial.print (recieved_data[2]);
  Serial.print (" J2 Y ");
  Serial.print (recieved_data[3]);
  Serial.print (" pot ");
  Serial.print (recieved_data[4]);
  Serial.print (" Sw_11 ");
  Serial.print (recieved_data[5]);
  Serial.print (" Sw_12 ");
  Serial.print (recieved_data[6]);
  Serial.print (" Sw_21 ");
  Serial.print (recieved_data[7]);
  Serial.print (" Sw_22 ");
  Serial.print (recieved_data[8]);
  Serial.print (" Sw_31 ");
  Serial.print (recieved_data[9]);
  Serial.print (" Sw_32 ");
  Serial.print (recieved_data[10]);
  Serial.print (" consumption ");
  Serial.println (recieved_data[11]);    

Все работает исправно, пока не включаю тумблер SW_31. Приемни виснет наглухо. Помогает только физическое выдергивание из USB и повторное втыкание. Включение всех остальных тумблеров в любой последовательности такого разрушительного эффекта не имеют.

 

Подскажите, люди добрые, куда дальше компать? Есть, конечно, вариант выкинуть обрабатывание данного события из кода вообще, но это же не наш метод!

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

Если важно, то тумблер подключен к пинам 9 и 10

SLKH
Offline
Зарегистрирован: 17.08.2015

vdm пишет:

Если важно, то тумблер подключен к пинам 9 и 10

Это интересно и интригующе.

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

SLKH пишет:

Это интересно и интригующе.

Хм, звучит волнующе... Что бы это могло значить?

kostyamat
Offline
Зарегистрирован: 16.11.2017

Желание пилить что либо похвально, вот только зачем это делать с нуля, ведь все уже распиляно до нас. Вот тут https://www.electronoobs.com/eng_arduino_tut86.php распилили на мелкие кубики. ))

5N62V
Offline
Зарегистрирован: 25.02.2016

c заполнением понятно. Непонятно зачем вам для передачи положения тумблера переменная int, но это тут не главное. Главное, что приведенная Вами информация не дает ни малейшего шанса Вам помочь: нет схемы включения, нет кода приемника или хотя бы блоков передачи и приема данных. На этом фоне инфа куда подключен тумблер ничего, кроме глума, вызвать не может. 

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

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

5N62V пишет:

c заполнением понятно. Непонятно зачем вам для передачи положения тумблера переменная int, но это тут не главное. 

Потому что я одним массивом объявил и данные с потенциометров (от 0 до 255) и тумблеров (0 или 1).

 

5N62V пишет:

 нет схемы включения, нет кода приемника

Схема примитивнейшая. Центральный контакт тумблера на землю, крайние к пинам. Через подключаемый подтягивающий резистор.

5N62V пишет:

нет кода приемника.

Код я почти весь выложил ранее, остальное - работа с переманными и с nrf. Но, добавлю.



/*
   Пример скетча "управление с телеметрией", то есть модуль ПЕРЕДАТЧИК
   шлёт на ПРИЁМНИК команды управления, ПРИЁМНИК при получении пакета данных
   отправляет ПЕРЕДАТЧИКУ пакет телеметрии (какие-то свои данные). ПЕРЕДАТЧИК
   эти данные принимает. Вот такие пироги. Также в этом примере реализован 
   расчёт RSSI (процент ошибок связи), на основании которого можно судить о 
   качестве связи между модулями.
*/

// ЭТО СКЕТЧ ПРИЁМНИКА!!!

//--------------------- НАСТРОЙКИ ----------------------
#define CH_NUM 0x60   // номер канала (должен совпадать с передатчиком)
//--------------------- НАСТРОЙКИ ----------------------

//--------------------- ДЛЯ РАЗРАБОТЧИКОВ -----------------------
// УРОВЕНЬ МОЩНОСТИ ПЕРЕДАТЧИКА
// На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
#define SIG_POWER RF24_PA_MIN

// СКОРОСТЬ ОБМЕНА
// На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
// должна быть одинакова на приёмнике и передатчике!
// при самой низкой скорости имеем самую высокую чувствительность и дальность!!
// ВНИМАНИЕ!!! enableAckPayload НЕ РАБОТАЕТ НА СКОРОСТИ 250 kbps!
#define SIG_SPEED RF24_1MBPS
//--------------------- ДЛЯ РАЗРАБОТЧИКОВ -----------------------

//--------------------- БИБЛИОТЕКИ ----------------------
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(7, 8);   // "создать" модуль на пинах 9 и 10 для НАНО/УНО

//--------------------- БИБЛИОТЕКИ ----------------------

//--------------------- ПЕРЕМЕННЫЕ ----------------------
byte pipeNo;
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; // возможные номера труб

int recieved_data[13];         // массив принятых данных
int telemetry[2];             // массив данных телеметрии (то что шлём на передатчик)
//--------------------- ПЕРЕМЕННЫЕ ----------------------

void setup() {
  Serial.begin(9600);
  radioSetup();
}

void loop() {
useRadio();
}

void radioSetup() {         // настройка радио
  radio.begin();               // активировать модуль
  radio.setAutoAck(1);         // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);     // (время между попыткой достучаться, число попыток)
  radio.enableAckPayload();    // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);    // размер пакета, байт
  radio.openReadingPipe(1, address[0]);   // хотим слушать трубу 0
  radio.setChannel(CH_NUM);               // выбираем канал (в котором нет шумов!)
  radio.setPALevel(SIG_POWER);            // уровень мощности передатчика
  radio.setDataRate(SIG_SPEED);           // скорость обмена
  // должна быть одинакова на приёмнике и передатчике!
  // при самой низкой скорости имеем самую высокую чувствительность и дальность!!

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

void useRadio()
{
    while (radio.available(&pipeNo)) {                                 // слушаем эфир
    radio.read( &recieved_data, sizeof(recieved_data));              // чиатем входящий сигнал

readRadio();

    // формируем пакет данных телеметрии (напряжение АКБ, скорость, температура...)
    telemetry[0] = 20;
    telemetry[1] = 20;

    radio.writeAckPayload(pipeNo, &telemetry, sizeof(telemetry));    // отправляем пакет телеметрии
  }
}

void readRadio()
{
  Serial.print ("J1 X ");
  Serial.print (recieved_data[0]);
  Serial.print (" J1 Y "); 
  Serial.print (recieved_data[1]);
  Serial.print (" J2 X ");
  Serial.print (recieved_data[2]);
  Serial.print (" J2 Y ");
  Serial.print (recieved_data[3]);
  Serial.print (" pot ");
  Serial.print (recieved_data[4]);
  Serial.print (" Sw_11 ");
  Serial.print (recieved_data[5]);
  Serial.print (" Sw_12 ");
  Serial.print (recieved_data[6]);
  Serial.print (" Sw_21 ");
  Serial.print (recieved_data[7]);
  Serial.print (" Sw_22 ");
  Serial.print (recieved_data[8]);
  Serial.print (" Sw_31 ");
  Serial.print (recieved_data[9]);
  Serial.print (" Sw_32 ");
  Serial.print (recieved_data[10]);
  Serial.print (" consumption ");
  Serial.println (recieved_data[11]);    
  
}

 

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

kostyamat пишет:

Желание пилить что либо похвально, вот только зачем это делать с нуля, ведь все уже распиляно до нас. Вот тут https://www.electronoobs.com/eng_arduino_tut86.php распилили на мелкие кубики. ))

Спасибо за ссылку! Очень позновательно!

SLKH
Offline
Зарегистрирован: 17.08.2015

vdm пишет:

Схема примитивнейшая. Центральный контакт тумблера на землю, крайние к пинам. Через подключаемый подтягивающий резистор.

Вы полагаете, что "тумблер подключен к пинам 9 и 10" следует понимать, как  "Центральный контакт тумблера на землю, крайние к пинам" ?

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

Ну что Вы... Я так не пологал... Яж исправился...

5N62V
Offline
Зарегистрирован: 25.02.2016

повторюсь: если тумблер двухпозиционный, то крайне расточительно использовать под него два пина.

По коду: мне кажется, что у Вас на каждый пришедший байт формируется ответная пачка и распечатывается листинг. Так должно быть?

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

5N62V пишет:

повторюсь: если тумблер двухпозиционный, то крайне расточительно использовать под него два пина.

А как тогда сделать? Добавить сопротивление и считывать analogRead?

5N62V пишет:

По коду: мне кажется, что у Вас на каждый пришедший байт формируется ответная пачка и распечатывается листинг. Так должно быть?

Почему на каждый байт? Так не должно быть.
Должно быть:
Пришел пакет данных - распечаталось полученное...

5N62V
Offline
Зарегистрирован: 25.02.2016

просто один пин тумблера на землю, а второй на пин ардуины. И считываете digitalRead. Ноль на входе соответствует одному положению тумблера, единица - другому. И три тублера  -  это три бита информации, а Вы сколько бит задействовали? правильный ответ 48 бит.

Если честно, лень копаться в библиотеке, может я ошибаюсь. А почему у Вас в настройках модуля пейлоад установлен 32 байта, а считываете Вы в массив длинной 26 байт?  Очень похоже, что это может быть проблемой

 

 

gfx125
Offline
Зарегистрирован: 27.05.2017

del

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

5N62V пишет:

просто один пин тумблера на землю, а второй на пин ардуины. И считываете digitalRead. Ноль на входе соответствует одному положению тумблера, единица - другому. 

Подождите, но я так сделал и написал, двухпозиционный тумблер, подключен к пинам 9 и 10, позже добавил, что средний контакт к земле, боковые к пинам. Считыываю digitalReadom, получаю либо 1 либо 0, полученное значение отправляю в массив...

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

vdm пишет:

Подождите, но я так сделал и написал, двухпозиционный тумблер, подключен к пинам 9 и 10

перечитайте еще раз. что вам написал 5N62V - не нужно там 2 пина, достаточно одного

Что касается массива для передачи данных - то, что у вас PayLoad = 32, а массив - 26, это не страшно.

Но вообзе с размером массива вы как-то странно обращаетесь. Выделили массив из 13 элементов, однако на передачике вы пишете в него всего 11 переменных, а на приемнике читаете 12... Почему?

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

b707 пишет:

перечитайте еще раз. что вам написал 5N62V - не нужно там 2 пина, достаточно одного

Я догадывался, что я многого не знаю... Но чтоб настолько... А можно схему?
 

b707 пишет:

Что касается массива для передачи данных - то, что у вас PayLoad = 32, а массив - 26, это не страшно.

Готовый код корректирую. Payload забил максимально, а массив под свои требования. Потом, когда с массивом разберусь, исправлю Payload

b707 пишет:

Но вообзе с размером массива вы как-то странно обращаетесь. Выделили массив из 13 элементов, однако на передачике вы пишете в него всего 11 переменных, а на приемнике читаете 12... Почему?

Массив на 13 элементов - чтобы с запасом. 

На передатчике 12-е значение - константа, она не считывается с датчиков

 

gfx125
Offline
Зарегистрирован: 27.05.2017

vdm пишет:

Я догадывался, что я многого не знаю... Но чтоб настолько... А можно схему?

При текущем подключении у вас на пинах 9 и 10 возможно всего два состояния 01 или 10. Т.е. если на 9-м будет 1, то на 10-м всегда 0. И наоборот. Поэтому достаточно считывать только, допустим, значение 9-го пина, а переменной соответствующей 10 пину присваивать инверсное значение первой. И в этом случае достаточно обычной кнопки на одном пине

 

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

vdm пишет:

А можно схему?

Да какая тут схема... Средний контакт тумблера к земле (GND), один из боковых контактов (любой) к пиному ардуины. Включаете подтяжку этого пина pinMode(pin, INPUT_PULLUP); и опрашиваете val = digitalRead(pin); Там будет либо 1, либо 0.

Имело бы смысл подключать оба боковых контакта, если б тумблер был трёхпозиционным (с тремя состояниями: 01-00-10)

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

gfx125 пишет:

 

Jeka_M пишет:

 

Коллеги, посыпаю голову пеплом, мой косяк в подсчете позиций. Тумблер трехпозиционный.

 

Но сути проблемы это не меняет...

kostyamat
Offline
Зарегистрирован: 16.11.2017

А лучше вообще читать тумблер аналоговым входом (один фиг их девать то куда-то нужно) через резисторы. Возможно когда-то захотите на его место галетник на пять- шесть позиций примастрачить. И вообще, я бы посмотрел у испанца (да он испанец, хотя страница на английском, та ссылка на мануал, что я выше давал) как все реализовано, и не страдал бы фигней. У него весь код хорошо и понятно документирован. Приемник сделан и для PWM и для PPM режимов. Вот охота вам велосипед изобретать?

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

Да яж не против чужого опыта перенять...

Есть не менее интересный проект:

https://howtomechatronics.com/projects/diy-arduino-rc-transmitter/

Что я хочу получить:

1. Возможность выбора модели. Есть 2 джойстика и 2 сына.  И желание делать РУ игрушки. Делать пульт под каждую игрушку - не варинат. Делать Один пульт на несколько игрушек - тоже. Вдруг захотят поиграть двумя игрушками, которые под один пульт заточены? Отсюда необходимо выбор модели.

Вот пример машинки: https://vk.com/id40096236?z=video40096236_456239027%2F7c74ddaea07fd002ba%2Fpl_wall_40096236

На текущий момент в данном пульте реализовано:

1. Возможность выбора модели.
2. Русский язык в меню
3. 4 дискретных канала
4. 2 аналоговых канала
5. Регулирование максимальной скорости модели (расходов)
6. Контроль получения сигнала приемником.

Но, протокол придется переписывать.

Что я хочу от второго пульта:

1. Выбор модели
2. Русский язык в меню
3. 5 аналоговых каналов
4. 6 дискретных каналов
5. Контроль получения сигнала приемником.

этого не дает ни один готовый вариант....

5N62V
Offline
Зарегистрирован: 25.02.2016

vdm пишет:

3. 5 аналоговыВх каналов

Вам предстоит определиться с разрешением каналов. От этого будет зависеть длина управляющей пачки. Больше разрешение - реже будет отправляться управляющая пачка, и наоборот.

vdm пишет:

5. Контроль получения сигнала приемником. 

  считаю подтверждение каждой почки бессмыссленным занятием. Для этого лучше применять дуплекс, иначе частота посыла управляющих пачек значительно снизится. Если конечно последняя имеет для Вас какое-то значение.

чем управлять собираетесь, ежели не секрет?

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

5N62V пишет:

Вам предстоит определиться с разрешением каналов. От этого будет зависеть длина управляющей пачки. Больше разрешение - реже будет отправляться управляющая пачка, и наоборот.

Разрешение 0-255, если я правильно Вас понял

5N62V пишет:

считаю подтверждение каждой почки бессмыссленным занятием. Для этого лучше применять дуплекс, иначе частота посыла управляющих пачек значительно снизится. Если конечно последняя имеет для Вас какое-то значение.

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

5N62V пишет:

чем управлять собираетесь, ежели не секрет?

Не секрет. 1 машина уже переделана, штук 5 еще ждут переделки. Планируем самолет построить :) Заказал по акции 4 мотора за 12 долларов, китаец прислал 8...

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

В общем, победил я сей недуг. И дело было не в бабине...

Схему собрал на макетных платах. При монтаже случайно припалил провод "земли" который шел на трехпозиционный тумбрер, при пайке "горки проводов" на модуле питания 3.3 вольта на "+" ноге накакал каплю с острым кончиком. И по закону жанра, припаленны  провод совпал с острым кончиком. А тиская постоянно плату сильнее сдавил место контакта получив КЗ. И при использовании данного тумблера нога соединялась не с землей, через подтягивающий резистор, а с каким-то питанием тем самым вешая контроллер... Думаю, что там было явно не 3.3. К моему удивлению, ничего не сгорело. 

 

На фото уже с замененным проводом.