arduino

Обсуждение увлечений, которые помогают нам скоротать свободное время
Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 00:56

Есть кто разбирается в программировании устройств arduino, помогите описать одну функцию.

Аватар пользователя
Bill Humble
Специалист
Специалист
Сообщений: 1521
Зарегистрирован: 09 июл 2009, 00:12
Темы: 6
Авто: A4Q 1.8T AMB '04
Имя:
Откуда: Логойск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Bill Humble » 14 фев 2017, 07:05

Не то, чтоб профессионально, но пишу понемногу. Что не получается?
Не умножай сущностей без надобности

Аватар пользователя
Rokky
Наездник
Наездник
Сообщений: 422
Зарегистрирован: 15 сен 2016, 14:41
Темы: 3
Авто: Audi A4 B8, 1.8 TFSI
Имя: Жека
Откуда: Минск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Rokky » 14 фев 2017, 09:29

я разбираюсь

сейчас вот как раз пилю проект по умному гаражу :)
Изображение

https://www.drive2.ru/r/audi/a4/453354483729040251/

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 14:01

Задача: есть заданный интервал времени, в течении которого мы ждём несколько последовательных команд, в случае окончания интервала времени и отсутствия заданных последовательных команд, выполняется определённое действие, а в случае правильного ввода команд, устройство не выполняет никаких действий. Проверка команд осуществляется при подаче питания на устройство. Если совсем грубо по задаче - проходим проверку. Очень важна правильная последовательность ввода команд.

Аватар пользователя
Rokky
Наездник
Наездник
Сообщений: 422
Зарегистрирован: 15 сен 2016, 14:41
Темы: 3
Авто: Audi A4 B8, 1.8 TFSI
Имя: Жека
Откуда: Минск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Rokky » 14 фев 2017, 14:05

Maxxtro2, так, это задача, а какую функцию написать?)

сразу вопросы возникают..:
какой формат команд?
как поступают команды на устройство?
RX/TX или через цифру или аналог?
пока идет интервал времени, идет процесс ввода команды на сколько большой этот пул команд который должна хранить плата?
Изображение

https://www.drive2.ru/r/audi/a4/453354483729040251/

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 14:21

Команды принимаем по CAN, туда же и отправляем команды. При приёме мы их отфильтровываем и проверяем. Команд по количеству на приемку ждем - до 10. На отправку, пока под вопросом.
Фильтрацию, проверку и отправку, уже осуществлял ранее, а вот фильтрацию в течении времени и по последовательности ввода, тут и застопорился

Аватар пользователя
Rokky
Наездник
Наездник
Сообщений: 422
Зарегистрирован: 15 сен 2016, 14:41
Темы: 3
Авто: Audi A4 B8, 1.8 TFSI
Имя: Жека
Откуда: Минск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Rokky » 14 фев 2017, 14:32

Maxxtro2, по факту вам нужен таймер, который по прошествии времени будет проверять вам массив команд

SomeType array[ItemCount]; - массив команд которые считали до того как сработал таймер
а по срабатыванию таймера бежим по всему этому массиву и смотрим:
array[i] = XXX и array[i+1] = YYY, то меняем например переменную, которая указывает, что надо или не надо выполнять действие на соответствующие значение

как, то так.
Кодом смогу наверное только сегодня вечером или завтра..

пс: при работе с таймером почитайте про прерывания на ардуине
Изображение

https://www.drive2.ru/r/audi/a4/453354483729040251/

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 14:41

Таймер, но только действие мы выполняем по его истечению, а вот фильтрацию и проверку мы проводим пока время не истекло

Аватар пользователя
Rokky
Наездник
Наездник
Сообщений: 422
Зарегистрирован: 15 сен 2016, 14:41
Темы: 3
Авто: Audi A4 B8, 1.8 TFSI
Имя: Жека
Откуда: Минск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Rokky » 14 фев 2017, 14:47

Maxxtro2, ну как я понимаю, у вас уже есть некий массив над которым вы делаете все эти шаманства, а потом скармливаете его таймеру, точнее функции которая будет вызваться по тику
можно вообще сделать, если нашли в вашей последовательности команд, стоп-команду, прибить таймер, и запустить его с начала

или я глупый и не до конца догнал вашу задачу :stars:
Изображение

https://www.drive2.ru/r/audi/a4/453354483729040251/

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 14:48

В моем случае я и использую прерывание (interrupt), так как с задержкой (delay) я уже столкнулся и понял что мы получаем остановку процесса работы, где и пропускаем нужные пакеты данных

Отправлено спустя 2 минуты 13 секунды:
Доберусь до компьютера, сброшу то, что есть и работает, к этому я хочу добавить таймер и вылавливание из данных последовательно поступивших команд

Аватар пользователя
Bill Humble
Специалист
Специалист
Сообщений: 1521
Зарегистрирован: 09 июл 2009, 00:12
Темы: 6
Авто: A4Q 1.8T AMB '04
Имя:
Откуда: Логойск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Bill Humble » 14 фев 2017, 18:45

Можно вообще не использовать 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()
Не умножай сущностей без надобности

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 19:09

Код: Выбрать все

#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. На этом работа устройства должна прекращаться и возобновляться только при следующем включении.
Последний раз редактировалось Maxxtro2 14 фев 2017, 23:48, всего редактировалось 1 раз.

Аватар пользователя
Bill Humble
Специалист
Специалист
Сообщений: 1521
Зарегистрирован: 09 июл 2009, 00:12
Темы: 6
Авто: A4Q 1.8T AMB '04
Имя:
Откуда: Логойск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Bill Humble » 14 фев 2017, 23:04

Не проверял, но должно работать как-то так

Код: Выбрать все

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 и проверки больше не выполняются.
Не умножай сущностей без надобности

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 23:15

Bill Humble, а как с вопросом последовательности?

Аватар пользователя
Bill Humble
Специалист
Специалист
Сообщений: 1521
Зарегистрирован: 09 июл 2009, 00:12
Темы: 6
Авто: A4Q 1.8T AMB '04
Имя:
Откуда: Логойск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Bill Humble » 14 фев 2017, 23:18

На первом условии проверяется первый байт буфера на совпадение с 32. На втором - второй байт. А как надо? Возможно я не очень понял условие задачи.
Не умножай сущностей без надобности

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 14 фев 2017, 23:28

Попробую по другому обьяснить

мы в строчке 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.

Аватар пользователя
alexstr81
Авторитет
Авторитет
Сообщений: 4739
Зарегистрирован: 30 авг 2010, 18:58
Темы: 0
Авто: А6 С6 (4f) 2.0 tdi BRF
VIN: WAUZZZ4F76N189674
Имя: Алекс
Откуда: Гомель
Статус: Не в сети

arduino

Сообщение alexstr81 » 15 фев 2017, 02:53

     Оффтопик:
Maxxtro2, это таким образом избавляемся от ошибки по диодам???
Сердце просит любви. Душа просит покоя . Тело просит разврата. Никому ничего не даю. Все сидят злые.

Аватар пользователя
Bill Humble
Специалист
Специалист
Сообщений: 1521
Зарегистрирован: 09 июл 2009, 00:12
Темы: 6
Авто: A4Q 1.8T AMB '04
Имя:
Откуда: Логойск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Bill Humble » 15 фев 2017, 07:02

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 логических переменных и зажигать каждую в зависимости от полученных данных и состояния остальных.
Не умножай сущностей без надобности

Аватар пользователя
Maxxtro2
Механик
Механик
Сообщений: 1024
Зарегистрирован: 10 ноя 2009, 00:46
Темы: 30
Имя:
Статус: Не в сети

arduino

Сообщение Maxxtro2 » 15 фев 2017, 10:00

Bill Humble, ругается на
then


alexstr81,
alexstr81 писал(а):Источник цитаты
     Оффтопик:
Maxxtro2, это таким образом избавляемся от ошибки по диодам???

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

Аватар пользователя
Bill Humble
Специалист
Специалист
Сообщений: 1521
Зарегистрирован: 09 июл 2009, 00:12
Темы: 6
Авто: A4Q 1.8T AMB '04
Имя:
Откуда: Логойск
Контактная информация:
Статус: Не в сети

arduino

Сообщение Bill Humble » 15 фев 2017, 11:27

Maxxtro2 писал(а):Источник цитаты ругается на then

Это я лишнего посидел за 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.
Не умножай сущностей без надобности


Вернуться в «На досуге...»

Кто сейчас на форуме

Количество пользователей, которые сейчас просматривают этот форум: нет зарегистрированных пользователей и 2 гостей