Страница 1 из 5
arduino
Добавлено: 14 фев 2017, 00:56
Maxxtro2
Есть кто разбирается в программировании устройств arduino, помогите описать одну функцию.
arduino
Добавлено: 14 фев 2017, 07:05
Bill Humble
Не то, чтоб профессионально, но пишу понемногу. Что не получается?
arduino
Добавлено: 14 фев 2017, 09:29
Rokky
я разбираюсь
сейчас вот как раз пилю проект по умному гаражу
arduino
Добавлено: 14 фев 2017, 14:01
Maxxtro2
Задача: есть заданный интервал времени, в течении которого мы ждём несколько последовательных команд, в случае окончания интервала времени и отсутствия заданных последовательных команд, выполняется определённое действие, а в случае правильного ввода команд, устройство не выполняет никаких действий. Проверка команд осуществляется при подаче питания на устройство. Если совсем грубо по задаче - проходим проверку. Очень важна правильная последовательность ввода команд.
arduino
Добавлено: 14 фев 2017, 14:05
Rokky
Maxxtro2, так, это задача, а какую функцию написать?)
сразу вопросы возникают..:
какой формат команд?
как поступают команды на устройство?
RX/TX или через цифру или аналог?
пока идет интервал времени, идет процесс ввода команды на сколько большой этот пул команд который должна хранить плата?
arduino
Добавлено: 14 фев 2017, 14:21
Maxxtro2
Команды принимаем по CAN, туда же и отправляем команды. При приёме мы их отфильтровываем и проверяем. Команд по количеству на приемку ждем - до 10. На отправку, пока под вопросом.
Фильтрацию, проверку и отправку, уже осуществлял ранее, а вот фильтрацию в течении времени и по последовательности ввода, тут и застопорился
arduino
Добавлено: 14 фев 2017, 14:32
Rokky
Maxxtro2, по факту вам нужен таймер, который по прошествии времени будет проверять вам массив команд
SomeType array[ItemCount]; - массив команд которые считали до того как сработал таймер
а по срабатыванию таймера бежим по всему этому массиву и смотрим:
array[i] = XXX и array[i+1] = YYY, то меняем например переменную, которая указывает, что надо или не надо выполнять действие на соответствующие значение
как, то так.
Кодом смогу наверное только сегодня вечером или завтра..
пс: при работе с таймером почитайте про прерывания на ардуине
arduino
Добавлено: 14 фев 2017, 14:41
Maxxtro2
Таймер, но только действие мы выполняем по его истечению, а вот фильтрацию и проверку мы проводим пока время не истекло
arduino
Добавлено: 14 фев 2017, 14:47
Rokky
Maxxtro2, ну как я понимаю, у вас уже есть некий массив над которым вы делаете все эти шаманства, а потом скармливаете его таймеру, точнее функции которая будет вызваться по тику
можно вообще сделать, если нашли в вашей последовательности команд, стоп-команду, прибить таймер, и запустить его с начала
или я глупый и не до конца догнал вашу задачу
arduino
Добавлено: 14 фев 2017, 14:48
Maxxtro2
В моем случае я и использую прерывание (interrupt), так как с задержкой (delay) я уже столкнулся и понял что мы получаем остановку процесса работы, где и пропускаем нужные пакеты данных
Отправлено спустя 2 минуты 13 секунды:
Доберусь до компьютера, сброшу то, что есть и работает, к этому я хочу добавить таймер и вылавливание из данных последовательно поступивших команд
arduino
Добавлено: 14 фев 2017, 18:45
Bill Humble
Можно вообще не использовать delay().
Есть функция millis() - количество миллисекунд с момента начала работы ардуины.
void loop()
{
if (got_event) {
prev_event = millis();
got_event = FALSE;
}
if (millis()-prev_event) >= 1000) {
do_timeout_code();
}
}
По прерыванию в отдельно функции получаем данные с SPI и анализируем. Если пришло то, что хотели, выставляем got_event в истину.
Если по истечению некоторого времени (1000 миллисекунд в моем примере) не было событий, считаем таймаут наступившим и выполняем процедуру do_timeout_code()
arduino
Добавлено: 14 фев 2017, 19:09
Maxxtro2
Код: Выбрать все
#include <mcp_can.h>
#include <SPI.h>
int A;
const int SPI_CS_PIN = 10;
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char str[20];
unsigned char stmp1[8] = {0, 0, 0, 0, 128, 0, 0, 0};
unsigned char stmp2[8] = {0, 0, 0, 1, 0, 0, 0, 0};
MCP_CAN CAN(SPI_CS_PIN);
void setup()
{
while (CAN_OK != CAN.begin(CAN_500KBPS))
pinMode(2, INPUT);
attachInterrupt(0, MCP2515_ISR, FALLING);
}
void MCP2515_ISR()
{
rxId, A;
}
void loop()
{
if (rxId == 0x3bc)
{
if (A = (unsigned char)rxBuf[0x01] == 32)
{
CAN.sendMsgBuf(0x3b4, 0, 8, stmp1);
delay(300);
}
}
if (rxId == 0x3bc)
{
if (A = (unsigned char)rxBuf[0x02] == 32)
{
CAN.sendMsgBuf(0x3b1, 0, 8, stmp2);
delay(300);
}
}
}
К этому необходимо: чтобы при включении устройства в первые 30 секунд шел поиск в буфере необходимых значений в rxId == 0x3bc, которые появляются последовательно, сначала rxBuf[0x01] == 32, а после xBuf[0x02] == 32. И если значения в течении 30 секунд найдены, то устройство молчит, а при их отсутствии идет посылка данных в 0x3b4 и 0x3b1. На этом работа устройства должна прекращаться и возобновляться только при следующем включении.
arduino
Добавлено: 14 фев 2017, 23:04
Bill Humble
Не проверял, но должно работать как-то так
Код: Выбрать все
boolean event1 = false;
boolean event2 = false;
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
if(!event2 && CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.readMsgBuf(&len, buf);
unsigned int canId = CAN.getCanId();
if (!event1 && canId == 0x3BC && buf[1] == 32) then event1 = true;
if (event1 && !event2 && canId == 0x3BC && buf[2] == 32) then event2 = true;
}
if (!event2 && millis() > 30000) {
unsigned char stmp1[8] = {0, 0, 0, 0, 128, 0, 0, 0};
CAN.sendMsgBuf(0x3b4, 0, 8, stmp1);
unsigned char stmp2[8] = {0, 0, 0, 1, 0, 0, 0, 0};
CAN.sendMsgBuf(0x3b1, 0, 8, stmp2);
event2 = true;
}
}
В бесконечном цикле крутятся две проверки. Их можно даже переставить, поведение не поменяется.
В первой ожидаем прихода информации. Если информация получена, выставляем флаг event2 и больше никогда ничего не делаем.
Во второй ожидаем наступления 30 секунд. Если они наступили и информация до сих пор не получена, отправляем данные и точно так же выставляем event2 и проверки больше не выполняются.
arduino
Добавлено: 14 фев 2017, 23:15
Maxxtro2
Bill Humble, а как с вопросом последовательности?
arduino
Добавлено: 14 фев 2017, 23:18
Bill Humble
На первом условии проверяется первый байт буфера на совпадение с 32. На втором - второй байт. А как надо? Возможно я не очень понял условие задачи.
arduino
Добавлено: 14 фев 2017, 23:28
Maxxtro2
Попробую по другому обьяснить
мы в строчке 3bc 8 00:00:00:00:00:00:00:00 ищем совпадение,
сперва 3bc 8 00:32:00:00:00:00:00:00, а после 3bc 8 00:00:32:00:00:00:00:00,
ели эта последовательность не выполнена, то совершаем отправку 3b4 8 00:00:00:00:128:00:00:00: и 3b1 8 00:00:00:1:00:00:00:00
В моем случае совпадение будет равняться около 10 значениям, а на отправку будет довольно много данных
Кстати дополнительно было бы неплохо прописать кроме последовательных данных и совместные, к примеру 3bc 8 00:32:32:00:00:00:00:00.
Отправлено спустя 1 час 18 минуты 45 секунды:и кстати по твоему сообщению
unsigned int canId = CAN.getCanId();
лучше писать
long unsigned int canId = CAN.getCanId();
чтобы принимала значения более 255 (FF). Иначе при фильтре мы не поймаем правильные и нужные Id.
arduino
Добавлено: 15 фев 2017, 02:53
alexstr81
Оффтопик:
Maxxtro2, это таким образом избавляемся от ошибки по диодам???
arduino
Добавлено: 15 фев 2017, 07:02
Bill Humble
Maxxtro2 писал(а):Источник цитаты мы в строчке 3bc 8 00:00:00:00:00:00:00:00 ищем совпадение,
сперва 3bc 8 00:32:00:00:00:00:00:00, а после 3bc 8 00:00:32:00:00:00:00:00,
ели эта последовательность не выполнена, то совершаем отправку 3b4 8 00:00:00:00:128:00:00:00: и 3b1 8 00:00:00:1:00:00:00:00
Как раз в моем примере кода должно работать и то и другое.
Как только в позиции 1 найдено 32, начинаем искать 32 в позиции 2, в том числе в текущем пакете.
Если поменять местами
Код: Выбрать все
if (event1 && !event2 && canId == 0x3BC && buf[2] == 32) then event2 = true;
if (!event1 && canId == 0x3BC && buf[1] == 32) then event1 = true;
То 32 на позиции 2 начнет искаться со следующего пакета после нахождения 32 на позиции 1.
А вообще можно завести хоть 20 логических переменных и зажигать каждую в зависимости от полученных данных и состояния остальных.
arduino
Добавлено: 15 фев 2017, 10:00
Maxxtro2
Bill Humble, ругается на
then
alexstr81,
alexstr81 писал(а):Источник цитаты Оффтопик:
Maxxtro2, это таким образом избавляемся от ошибки по диодам???
Можно пробовать любой чек, но тут все зависит от количества посылок, шину можно легко перегрузить. В этом случае можно просто слать бит с меньшей задержкой.
arduino
Добавлено: 15 фев 2017, 11:27
Bill Humble
Это я лишнего посидел за Delphi на работе. Ну какой "then" в языке C?
Код: Выбрать все
if (!event1 && canId == 0x3BC && buf[1] == 32) event1 = true;
if (event1 && !event2 && canId == 0x3BC && buf[2] == 32) event2 = true;
Maxxtro2 писал(а):Источник цитаты лучше писать long unsigned int canId = CAN.getCanId();
unsigned int - это уже 16 бит. У нас будут на шине id больше чем 2 байта?
alexstr81 писал(а):Источник цитаты это таким образом избавляемся от ошибки по диодам???
Цель вторична. Полюбому научиться работать с автомобильным CAN весьма полезно. Вот например знакомого бесит, что китайский CAN-бридж от китайской автомагнитолы вырубает ее через 10 минут после выключения зажигания. Умел бы программировать - сделал бы собственный бридж с 30 минутами вместо 10.