Русский
Русский
English
Статистика
Реклама

Arduino uno

Из песочницы Использование контроллера Arduino для прерываний

18.07.2020 12:13:16 | Автор: admin
В данной стать я приведу пример использования arduino контроллера для вызова прерываний программы на C#.

Стоит отметить, что в WindowsForms присутствует элемент Timer который включается и выполняет код через определенный промежуток времени.



Я решил реализовать подобное используя микроконтроллер Arduino UNO.

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

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

void setup(){Serial.begin(9600);//Открыть последовательный порт}int str=0;int interval=0;String text;void loop(){while(str==0) str=Serial.parseInt();//Ждать прихода данных  if (str==1)//Если поступила команда запуска таймера  { while(interval==0)   interval=Serial.parseInt();//получить интервал text=String(interval); text+="!"; while(str!=2){delay(interval);//Подождать указанный промежуток времени Serial.println(text);//Отправить данные в последовательный порт str=Serial.parseInt();//Ждать следующей комнды } interval=0;  }}

Также контроллер принимает команды запуска(1) и остановки(2) таймера. (Аналог методов start и stop для таймера windowsforms).

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

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Threading;using System.IO.Ports;using System.IO;using System.Net;namespace ConsoleApp33{    class Program    {        private static SerialPort ard = new SerialPort("COM13", 9600);//Название порта к которому подключен контроллер и скорость обмена данными с портом.        private static Thread stop_thread = new Thread(Stop);        private static bool sost = true;       [MTAThread]        static void Main(string[] args)        {                       SerialDataReceivedEventHandler handler = new SerialDataReceivedEventHandler(Serial_interrupt);//Метод выполняемый при приходе данных            ard.DataReceived += handler;            //Задать интервал задержки            int interval = int.Parse(Console.ReadLine());            //Открыть последовательный порт            while (ard.IsOpen != true)                ard.Open();            //Запустить контроллер            ard.WriteLine("1");            Thread.Sleep(10);            ard.WriteLine(interval.ToString());            Console.WriteLine(ard.ReadLine());            //Запуск потока остановки контроллера            stop_thread.IsBackground = true;                     stop_thread.Start();                     while (sost) Thread.Sleep(1);//Приостановить поток        }        public enum Comand        {          Start = 1,//Запуск таймера         Stop = 2   //Остановка таймера        }        private static System.DateTime dateTime;        public static void Serial_interrupt(object sender,SerialDataReceivedEventArgs e)        {            //Вывести дату и время в консоль            dateTime = DateTime.Now;            Console.WriteLine(dateTime.ToString());        }        public static void Stop()        {            if ((int)Console.ReadKey().Key == 27)//Если нажата клавиша Esc выключить контроллер            {                ard.WriteLine(Comand.Stop.ToString());//Выклюить контроллер                sost = false;//Завершить Main            }            Thread.Sleep(10);        }          }}

Программа на C# открывает соединение с портом и при приходе данных возникает событие

ard.DataReceived += handler;

вызывающее метод Serial_interrupt(), который выводит в консоль дату и время компьютера.

Также присутствует поток stop_thread который завершает программу и отправляет на контроллер команду выключения когда нажимается клавиша Esc.

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

Всем спасибо за внимание.
Подробнее..

Победа над nRF24L01 на три шага ближе

25.02.2021 00:07:45 | Автор: admin

Многие испытывают трудности при соединении по эфиру радиомодулей nRF24L01. Об этом свидетельствует тема на форуме Амперки, открытая в конце 2014г. За пять с небольшим лет в теме накопилось более 120(!) страниц. Это при том, что автор темы не просто обозначил проблему, а поделился своим трехнедельным опытом победного для него боя. Кроме того, он тут же в первом сообщении создал навигатор по страницам темы, где приводит ссылки на решения проблемы другими. Этот своеобразный путеводитель постоянно обновляется.



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



Модули nRF24L01 работают в полудуплексном режиме. Это как разговор порации: каждый из корреспондентов в один момент времени либо говорит, либо слушает. То есть, каждый из двух узлов работает в режиме и приемника и передатчика: передатчик, отправив сообщение ждет на подтверждение приема сообщения со стороны приемника.



Как правило, все тесты, которые мне встречались в Инете, сводятся к проверке работы и качества связи пары радиомодулей в полнофункциональном режиме, когда передатчик, послав пакет, ждет на подтверждение приема пакета приемником.



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



Итак ...





Шаг 1



Загрузить в контроллер платы Ардуино скетч сканера эфира, который можно найти среди примеров Arduino IDE: Файл -> Примеры -> RF24 -> scanner. Ниже под спойлером есть этот скетч с несущественным изменением. В нем изменено время между стартом и остановкой сканирования одного канала с 128 мксек на 512 мксек. Увеличение времени позволило за один цикл выявлять бОльше источников помех и сигналов. Это равнозначно замене результата измерений в канале на сумму результатов в этом канале за четыре цикла сканирования эфира до изменения времени задержки. При этом, время прохода всего прослушиваемого диапазона сканером увеличилось несущественно: примерно с 8-ми до 10-ти сек.



В разных скетчах адрес канала в командах приводится в разных форматах: в одних ...(0x6f), в других ...(112). Перевод с одного формата в другой станет понятным с примера перевода. Например, для (0x1а) это: (1+1)*16 + а = (1+1)*16 + 10 = 42. Отсчет каналов начинается с частоты 2,4 ГГц, далее идет увеличение частоты на 1 МГц с увеличением номера канала на 1.



скетч сканера эфира
/*Победа над nRF24L01: на три шага ближе, сканер эфираhttp://personeltest.ru/aways/habr.com/ru/post/476716/*//*  Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>  This program is free software; you can redistribute it and/or  modify it under the terms of the GNU General Public License  version 2 as published by the Free Software Foundation.*//**   Channel scanner   Example to detect interference on the various channels available.   This is a good diagnostic tool to check whether you're picking a   good channel for your application.   Inspired by cpixip.   See http://arduino.cc/forum/index.php/topic,54795.0.html*/#include <SPI.h>#include "nRF24L01.h"#include "RF24.h"#include "printf.h"//// Hardware configuration//// Set up nRF24L01 radio on SPI bus plus pins 9 & 10RF24 radio(9, 10); //Arduino UNO//// Channel info//const uint8_t num_channels = 128;uint8_t values[num_channels];//// Setup//void setup(void){  //  // Print preamble  //  Serial.begin(57600);  Serial.println("Scanner Air On");  printf_begin();  //  // Setup and configure rf radio  //  radio.begin();  radio.setAutoAck(false);  // Get into standby mode  radio.startListening();  radio.stopListening();  // Print out header, high then low digit  int i = 0;  while ( i < num_channels )  {    printf("%x", i >> 4);    ++i;  }  printf("\n\r");  i = 0;  while ( i < num_channels )  {    printf("%x", i & 0xf);    ++i;  }  printf("\n\r");}//// Loop//const int num_reps = 100;void loop(void){  // Clear measurement values  memset(values, 0, sizeof(values));  // Scan all channels num_reps times  int rep_counter = num_reps;  while (rep_counter--)  {    int i = num_channels;    while (i--)    {      // Select this channel      radio.setChannel(i);      // Listen for a little      radio.startListening();      delayMicroseconds(512);      radio.stopListening();      // Did we get a carrier?      if ( radio.testCarrier() )        ++values[i];    }  }  // Print out channel measurements, clamped to a single hex digit  int i = 0;  while ( i < num_channels )  {    printf("%x", min(0xf, values[i] & 0xf));    ++i;  }  printf("\n\r");}// vim:ai:cin:sts=2 sw=2 ft=cpp



Далее подключаем модуль nRF24L01 к плате Ардуино или любому прототипу, собранному, допустим, на контроллере ATMEGA328P. Я собрал два образца на платах для прототипирования на контроллере ATMEGA328P по схеме контроллер + резонатор. Один образец подключаю к компу через плату Arduino UNO, а второй через конвертор USB/TTL.

Мощность стабилизатора платы Arduino UNO вполне приемлема для подключения дополнительной импульсной нагрузки такой, как nRF24L01+ c адаптером 5В/3,3В для этого модуля или без адаптера.





На мониторе последовательного порта Arduino IDE увидите нечто похожее:





Если вы увидели похожую картинку тест на работоспособность (исправность) радиомодуля и правильность его подключения пройден успешно. Замените радиомодуль другим, с которым планируете работать дальше.



Обратите внимание на чистый диапазон, начиная с канала 4а. У меня он остается чистым даже, если на расстоянии нескольких метров работает старая СВЧ-печь мощный источник помех в этом диапазоне. А в общем-то, в Интернете рекомендуют выбирать каналы для своих проектов выше 60.



Если на каналах шум, но радиомодуль определяется (смотрим преамбулу на мониторе Arduino IDE, подробно тут) это однозначно копия (подделка). Не отчаивайтесь ее тоже можно запустить.



Шаг 2



По схеме, аналогичной первой собираем второй радиоузел. Это будет передатчик. В его контроллер загружаем скетч передатчика (под спойлером).



скетч приемника
/*Победа над nRF24L01: на три шага ближе, приемникhttp://personeltest.ru/aways/habr.com/ru/post/476716/*/#include <SPI.h>#include <RF24.h>RF24 radio(9, 10); // порты D9, D10: CSN CEconst uint32_t pipe = 111156789; // адрес рабочей трубы;byte data;void setup() {  Serial.begin(115200);  Serial.println("TransmitterTester ON");  radio.begin();                // инициализация  delay(2000);  radio.setDataRate(RF24_1MBPS); // скорость обмена данными RF24_1MBPS или RF24_2MBPS  radio.setCRCLength(RF24_CRC_8); // размер контрольной суммы 8 bit или 16 bit  radio.setPALevel(RF24_PA_MAX); // уровень питания усилителя RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX  radio.setChannel(0x6f);         // установка канала  radio.setAutoAck(false);       // автоответ  radio.setRetries(0, 15);  //время между попыткой достучаться, число попыток  radio.powerUp();               // включение или пониженное потребление powerDown - powerUp  radio.stopListening();  //радиоэфир не слушаем, только передача  radio.openWritingPipe(pipe);   // открыть трубу на отправку}void loop() {  data = 109;  radio.write(&data, 1);  Serial.println("data= " + String(data));}



Передатчик без пауз в работе передает сигнал на канале 6f (112).



Подаем питание на сканер эфира и передатчик. Присмотритесь что творится на канале 6f и соседних с ним каналах. Сканер эфира при включенном передатчике рано или поздно прорисует единички или другие одноразрядные числа в шестнадцатиричном исчислении в области 6f, на который запрограммирован передатчик. Наберитесь терпения, особенно при работе со сканером из примеров.





Увидев сигнал от передатчика делаем следующий шаг.



Шаг 3



Загружаем вместо сканера скетч приемника (под спойлером).



скетч приемника
/*Победа над nRF24L01: на три шага ближе, передатчикhttp://personeltest.ru/aways/habr.com/ru/post/476716/*/#include <SPI.h>#include "nRF24L01.h"#include "RF24.h"RF24 radio(9, 10); // порты D9, D10: CSN CEconst uint32_t pipe = 111156789; // адрес рабочей трубы;byte data[1];int scn;  //счетчик циклов прослушивания эфираint sg;  //счетчик числа принятых пакетов с передатчикаvoid setup() {  Serial.begin(9600);  Serial.println("ReceiverTester ON");  radio.begin();  // инициализация  delay(2000);  radio.setDataRate(RF24_1MBPS); // скорость обмена данными RF24_1MBPS или RF24_2MBPS  radio.setCRCLength(RF24_CRC_8); // размер контрольной суммы 8 bit или 16 bit  radio.setChannel(0x6f);         // установка канала  radio.setAutoAck(false);       // автоответ  radio.openReadingPipe(1, pipe); // открыть трубу на приём  radio.startListening();        // приём}void loop() {  if (scn < 1000)  { // прослушивание эфира    if (radio.available())    {      radio.read(data, 1);      if (data[0] == 109) {        sg++;      }    }  } else {//всего принято    {      Serial.println("Принято: " + String(sg) + " пакетов");      sg = 0;    }    scn = 0;  }  scn++;  delay(20);  if (scn >= 1000) scn = 1000; //защита от переполнения счетчика}



Логика работы приемника такая же, как и у сканера эфира, но он в отличие от сканера принимает сигналы только на частоте передатчика 6f и, как и сканер, не посылает автоответ. Скорость обмена информацией и размер контрольной суммы у приемника такие же, как у передатчика. После каждых 1000-и циклов прослушивания в скетче обнуляется счетчик числа циклов и выводится инфа о количестве принятых пакетов с передатчика в монитор порта Arduino IDE.



Включаем передатчик и приемник. Если приемник принимает хотя бы каждый третий пакет это уже успех. У меня не получилось. Приемник по непонятным причинам принимал максимум 40 пакетов.



Подумал о увеличении мощности передаваемого сигнала с помощью дополнительной антенны. Для начала, подключил зажимом монтажный провод папа-мама к корню штатной антенны. И счастье привалило сразу 999 принятых пакетов!



Юзерам, которые захотят сделать все грамотно, придется поработать. Дополнительная антенна в данном случае это отрезок коаксиального кабеля с волновым сопротивлением 50 Ом и длиной 115 мм. Антенна подключается к выводу 13 (АNT2) микросхемы nRF24L01+. Схему подключения и номиналы нескольких недостающих smd компонентов, которые надо поставить на плату радиомодуля, можно найти на принципиальной электрической схеме nRF24L01+ тут. Впрочем, есть альтернатива в магазин за NRF24L01+PA+LNA





Теперь обязательно припаиваем между пинами GND и VCC обеих радиомодулей по два конденсатора. Керамический конденсатор, выполняющий роль ВЧ-фильтра, емкостью не менее 0,15 мкФ (чем больше, тем лучше) и электролит емкостью около 10 мкФ (можно и больше, но бесполезно) это НЧ-фильтр. ВЧ-фильтр шунтирует высокочастотные помехи по цепи питания радиомодуля, а НЧ-фильтр сглаживает пульсации питания. Для надежности, цепи питания радиомодулей лучше непосредственно подпаять к пинам контроллеров.



Все. Надеюсь, у вас в дальнейшем поубавится проблем с nRF24L01 в своих проектах. Успехов!



Безусловно эти простые шаги не могут гарантировать решение всех проблем с nRF24L01 мне их и не перечесть, но теперь вы, как и я, будете уверены:


  • радиомодули не бракованные;
  • подключены верно;
  • уровень сигнала передатчика, чуствительность приемника удовлетворительны и, в случае необходимости, обеспечиваются дополнительной антенной;
  • пара nRF24L01+ однозначно работает в режиме передатчик-приемник без откликов и их ожидания. Иногда этого достаточно.


Ссылки по теме



  1. Обзор радио модуля NRF24L01+
  2. nRF24L01+: побеждаем модуль.
  3. nRF24L01 и Ардуино: побеждаем модуль (видео)
  4. SE8R01. Подделка под NRF24L01 (видео)
  5. Обзор радио модуля NRF24L01+PA+LNA
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru