Очередной "Умный дом", на этот раз модульная система...

riv
Offline
Зарегистрирован: 20.07.2017

Я вот как то так вижу свой УД по автоматике, Мультирум и пр. умы это другой слой

MaksVV
Offline
Зарегистрирован: 06.08.2015

Можешь выложить картинку в полном качестве? А то плохо видно. На я диск например. В общем с длинными ID я чето намучился, не получалось у меня. Не только канхакер их не видел, но и не отправлялись они вовсе. Использовал видимо корявую библиотеку. Она называлась также, как ты давал по ссылке, поэтому я твою не стал скачивать. А моя видать корявая с длинными ID не работает. Уже после того, как с 11бит все сделал у себя, твою либу попробовал. Вроде норм 29бит отправляет. Может переделаю еще. А то действительно 16 адресов может и не хватить. Вдруг меня растащщит)

P.S. Или ещё может ничего не получалось, т.к. один CAN модуль у меня был неисправный. Он отправлял СAN феймы, но не принимал. 

riv
Offline
Зарегистрирован: 20.07.2017
riv
Offline
Зарегистрирован: 20.07.2017

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

Вот примерно мой can_struct.h (он общий для всех прошивок. Контролллеров то много в сети). И да удобнее с десятичными работать нежели с байтом. Тут на вкус и цвет, просто обработка строки быстрее пишется на мой взгляд. и на этапе прототипа мне так удобнее.

Я не проф. программер, я связист.

001#include <mcp_can.h>
002#include <SPI.h>
003 
004//ID structure   xx.yy.z.a.cc
005//      xx              yy                                     z             a                  cc
006//  my address   remote address    type message  device address     device type
007 
008//Node Address
009int global_mfg;
010//Основные помещения
011uint32_t  Livingroom_main_11    = 11;  // Гостинная основной
012uint32_t  Bedroom_main_21    = 21;  // Спальня основной
013uint32_t  Cabinet_main_31   = 31;  // Кабинет основной
014uint32_t  Hallway_main_41   = 41;  // Холл основной
015//Мокрая зона
016uint32_t  Kitchen_main_51   = 51;  // Кухня основной
017uint32_t  WC_main_61   = 61;  // Туалет основной
018uint32_t  WC_waterleak_62   = 62;  // Туалет защита от протечек
019uint32_t  Bathroom_71   = 71;  // Ванна основной
020uint32_t  Boxroom_81   = 81;  // Кладовая основной
021uint32_t  Loggia_main_82   = 82;  // Лоджия основной
022uint32_t  Balcony_83   = 83;  // Балкон основной
023 
024//Ядро сети и свет
025uint32_t  Hallway_net_center_91   = 91;  // Холл ядро сети
026uint32_t  Hallway_light_92   = 92;  // Холл ядро сети свет
027uint32_t  Kitchen_net_center_95   = 95;  // Кухня ядро сети
028uint32_t  Kitchen_light_96   = 96;  // Кухня ядро сети свет
029 
030uint32_t  rxId;
031 
032//Type message
033uint32_t  msg_tx_cmd_snd = 1; // NORMAL SEND COMMAND
034uint32_t  msg_rx_cmd_ans = 2; // NORMAL ANSVER COMMAND
035uint32_t  msg_tx_par_req = 3; // NORMAL SEND REQUEST
036uint32_t  msg_rx_par_ans = 4; // NORMAL ANSVER COMMAND
037uint32_t  msg_tx_stat_req = 5; //NORMAL SEND STATUS REQUEST
038uint32_t  msg_rx_stat_ans = 6; //NORMAL ANSVER STATUS COMMAND
039 
040//device type
041//Sensor
042uint32_t  air_temp_cens = 1;
043uint32_t  air_hum_cens = 2;
044uint32_t  air_pres_cens = 3;
045uint32_t  motion_pir_cens = 4;
046uint32_t  motion_mw_censor = 5;
047uint32_t  vibration_censor = 6;
048uint32_t  noise_censor = 7;
049uint32_t  Illumination_censor = 8;
050uint32_t  gas_co_censor = 9;
051uint32_t  gas_co2_censor = 10;
052uint32_t  gas_metan_censor = 11;
053uint32_t  smoke_censor = 12;
054uint32_t  fire_censor = 13;  //Огонь
055uint32_t  body_temperature_censor = 14;  //Температура тела
056uint32_t  jalousie_status_censor  = 15;  //Жалюзи
057uint32_t  steam_censor      = 16; //Пар
058uint32_t  microwave_censor = 17; //Излучение микроволновки
059uint32_t  fridge_temperature_censor = 18; //Холодильник
060uint32_t  freezer_temperature_censor = 19; //Морозилка
061uint32_t  oven_temperature_censor = 20; //Духовка
062uint32_t  electrical_board_censor = 21; //Электрощит концевик
063uint32_t  door_lock_censor = 22; //Замок двери
064uint32_t  door_close_censor = 23; //Замок двери
065uint32_t  motion_door1_censor = 24; //Датчик прохода 1
066uint32_t  motion_door2_censor = 25; //Датчик прохода 2
067uint32_t  window_close_censor = 26; //Закрыто
068uint32_t  water_hot_temperature_censor = 27; //Температура горячей воды
069uint32_t  water_cold_temperature_censor = 28; //Температура холодной воды
070uint32_t  water_hot_pressure_censor = 29; //Давление горячей воды
071uint32_t  water_cold_pressure_censor = 30; //Давление холодной воды
072uint32_t  leakage_censor = 31; //Протечка
073uint32_t  counter_gas_censor = 32; //Счетчик газа
074uint32_t  counter_water_hot_censor = 33; //Счетчик горячей воды
075uint32_t  counter_water_cold_censor = 34; //Счетчик холодной воды
076uint32_t  counter_electricity_censor = 35; //Счетчик электричества
077uint32_t  cupboard_door_censor = 36; //Дверь шкафа
078uint32_t  safe_door_censor = 37; //Дверь сейфа
079uint32_t  balcony_door_censor = 38; //Дверь балкона
080uint32_t  loggia_door_censor = 39; //Дверь лоджии
081uint32_t  radiator_temperature_censor = 40; //Температура батареи
082uint32_t  lamp_ceiling_censor = 41; //Лампа на потолке
083uint32_t  lamp_wall_censor = 42; //Ланпа настенная
084uint32_t  lamp_Illumination_censor      = 43; //Лампа подсветки
085uint32_t  lamp_accident_censor = 44; //Лампа аварийная
086uint32_t  earth_humidity_censor = 45; //Влажность земли
087uint32_t  lamp_aquarium_censor = 46; //Лампа аквариум
088uint32_t  aquarium_temperature_censor = 47; //Температура аквариум
089uint32_t  aquarium_pump_censor          = 48; //Насос аквариум
090uint32_t  aquarium_clearing_censor      = 49; //Очистка аквариум
091// темп рекуператора
092//темп, вл, давл, улица
093 
094 
095//Device Digital //Device analog
096uint32_t  lamp_ceiling_onoff_device = 60; //Лампа на потолке вкл/выкл
097uint32_t  lamp_wall_onoff_device = 61; //Ланпа настенная вкл/выкл
098uint32_t  lamp_Illumination_onoff_device = 62; //Лампа подсветки вкл/выкл
099uint32_t  lamp_accident_onoff_device = 63; //Лампа аварийная вкл/выкл
100uint32_t  lamp_ceiling_dimm_device = 64; //Лампа на потолке диммируемая
101uint32_t  lamp_wall_dimm_device = 65; //Ланпа настенная диммируемая
102uint32_t  lamp_Illumination_dimm_device = 66; //Лампа подсветки диммируемая
103uint32_t  lamp_accident_dimm_device = 67; //Лампа аварийная диммируемая
104uint32_t  fan                            = 68;
105uint32_t  recuperator                    = 69;
106uint32_t  air_conditioning              = 70;
107uint32_t  valve_radiator                = 71;
108uint32_t  jalousie                      = 72;
109uint32_t  valve_gas                      = 73;
110uint32_t  valve_hot_water                = 74;
111uint32_t  valve_cold_water              = 75;
112uint32_t  irda                          = 76;
113uint32_t  freshener                      = 77; //Освежитель
114uint32_t  humidifier                    = 78; //Увлажнитель
115uint32_t  door_lock_magnet              = 79;
116uint32_t  door_lock_electromagnet        = 80;
117uint32_t  door_lock_electromechanical    = 81;
118uint32_t  door_lock_blink                = 82;
119uint32_t  siren                          = 83;
120uint32_t  blinker                        = 84;
121uint32_t  music                          = 85;
122uint32_t  tv                            = 86;
123uint32_t  radio                          = 87;
124uint32_t  power_socket                  = 88; //Розетки
125 
126unsigned char len = 0;
127unsigned char rxBuf[8];
128unsigned char txBuf[8];
129char msgString[128];                          // Array to store serial string
130#define CAN0_INT 2                                // Set INT to pin 2
131MCP_CAN CAN0(53);                               // Set CS to pin (NANO, UNO etc = 10, MEGA,DUE etc = 53)

 

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Жесть какой широкий у тебя размах). У меня два вопроса. Зачем применяешь uint32_t. Неужели uint16_t не хватит? И второе , смотри самый первый разряд в ID тот который ХХ, имеет не весь диапазон адресов ( не 256) , т.к первый ниббл Х может принимать значения только от 0 до 7. Потому что ID 29 бит, а не 32. Т.е на этот ниббл Х отводится 3 бита вместо четырех.

riv
Offline
Зарегистрирован: 20.07.2017

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

uint32_t первое что под руку подвернулось ;-) (Я не проф программер, самоучка можно сказать). Памяти пока хватает. Потом переделаю все на Byte. Так проще писать адреса без пересчета, в десятичной системе. Это была проба пера, в смысле проверить CAN сеть, погонять обмен датчиков, включение выключение светодиодов на обратных концах и пр. Все заработало. Технология выбрана. Кабели запроектированы, заложены, штукатуркой замазаны, потолками закрыты. Я как конструктор ОКР иду от эскизного проекта к опытному образцу, через отработку технологий и макетирование, почти по 203 госту ;-) 

По поводу 29 а не 32 я поздно заметил, а сейчас смысла нет пока менять, адресов хватает. Ну и см. выше, это прототип. Важно определиться с концепцией. Мало того твои идеи оч. интересны.

Кстати начал тут глубже копать CAN так вот эти 3 бита забирает т.н. удаленный кадр, в котором нет поля данных но он является запросчиком. (Вернее даже не удаленный кадр а типизация видов сообщений)

"Удаленные кадры можно использовать для реализации управления трафиком шины типа «запрос–ответ». На практике, однако, удаленный кадр используется мало. Это не так важно, поскольку стандарт CAN не предписывает действовать именно так, как здесь обозначено. Большинство контроллеров CAN можно запрограммировать так, что они будут автоматически отвечать на удаленный кадр, или же вместо этого извещать локальный процессор."

http://www.micromax.ru/solution/theory-practice/articles/2160/

Умный дом у меня на самый конец уходит. Сейчас пока автоматика на реле. Бистабильные фото и пр. Т.е базовые вещи типо свет, вода и пр. работают без контроллеров.  Все системы при отключении УД продолжают нормально работать.

Ну и мы же реально умный дом делаем а не ПДУ для лампочек, для этого такой огород ведь не городят ;-)

P.S. использую вот эту библиотеку CAN  https://github.com/coryjfowler/MCP_CAN_lib

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

да, прототип хорош. На счет работы без контроллеров, ну не знаю. Вот у меня свет на втором этаже уже два года только в схеме с МК работает - выключатели света слаботочные на 5В, подают только сигнал на МК. Проблем не было никаких, даже в сильную грозу. Главное применять опторазвязки, провода в экране. А если коряво подходить к вопросу, дак и без МК что нибудь сгореть, сломаться может.

По поводу ID поменяй местами разряды и делов то:  Z.XX.YY.A.CC

где Z - тип сообщения, их у тебя 6, ещё 1 в запасе остаётся. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:
Так проще писать адреса без пересчета, в десятичной системе.

дак никто не мешает писать в десятичной системе на типе byte . Контроллеру то пофиг, ему всё одно - нули и единицы. просто пишешь число и всё - будет десятичная, если добавить перед записью числа 0x  - это HEX. Если добавить B - бинарная запись (в битах). 

riv
Offline
Зарегистрирован: 20.07.2017

Я не  точно объяснил. 

Использую бистабтльные реле РИО-1М и кнопочные выключатели. В паралель к кнопкам ставлю ТТ реле которым управлю с ардуино. Т.о. даже при отсутствии контроллеров свет управлется. И т.д. В дальнейшем при сбое или поломке контроллера я не сижу при свечах. Опторазвязки я естественно буду использовать. Нарпимер АОТ166 для проверки наличия напржения на лампах освещения.  Строю 2х уровневую, даже 3х уровневую систему. 1 уровень пром. реле. Второй уровень автоматика на МК, 3 уровень сцены на Сервере.

И дело даже не в надежности. Если бы я поше по пути контроллера то сидел бы без света сейчас. А так реле потавил и все работает. Сверху поставлю МК и буду им щелкать реле в паралель с кнопками. 

Насчет стрктуры - отличная идея.

riv
Offline
Зарегистрирован: 20.07.2017

Я вроде с этим тыкался, но для отладки быстрее выводиь все что пришло в сериал, а там опять преобразования. Естественно потом напишу.

Вот тут мои наброски https://yadi.sk/d/7pyVRdHJ3TNYXr

MaksVV
Offline
Зарегистрирован: 06.08.2015

имхо, у тебя замороченная схема извлечения разрядов из ID

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:
Использую бистабтльные реле РИО-1М и кнопочные выключатели. В паралель к кнопкам ставлю ТТ реле которым управлю с ардуино. Т.о. даже при отсутствии контроллеров свет управлется. И т.д. В дальнейшем при сбое или поломке контроллера я не сижу при свечах. Опторазвязки я естественно буду использовать. Нарпимер АОТ166 для проверки наличия напржения на лампах освещения.  Строю 2х уровневую, даже 3х уровневую систему. 1 уровень пром. реле. Второй уровень автоматика на МК, 3 уровень сцены на Сервере.

И дело даже не в надежности. Если бы я поше по пути контроллера то сидел бы без света сейчас. А так реле потавил и все работает. Сверху поставлю МК и буду им щелкать реле в паралель с кнопками.

ну в общем да, согласен, так наверное лучше. Понятно, что когда строишь систему УД делаешь много ошибок. Я если бы сейчас начинал, всё вообще бы не так сделал. А щас переделывать ужё лень - слишком много делов 

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

Я вроде с этим тыкался, но для отладки быстрее выводиь все что пришло в сериал, а там опять преобразования.

вот это не понял немного. Какие преобразования. Для отладки я использую CAN сниффер. Мне почему удобнее работать с HEX, так как все анализаторы CAN шины выводят инфу в HEX и визуально уже привыкаешь все адреса и байты видеть в HEX. А без анализаторы шины при построении тайой системы я вообще не знаю как можно обойтись. Я почему в своей 11битной схеме ID  и отказался от 5 битных адресов, потому как их визуально мониторить вообще проблема. Хотя так было бы 32 адреса, а не 16. 

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Я конечно тоже далекооо не крутой программист, вернее вообще не программист, но

с функцией void TX()  нужно тебе подумать 

1void TX(uint32_t node_to, uint32_t msg_type, uint32_t  dev_num, uint32_t  dev_type, float a, float b, float c, float d, float e, float f, float g, float h)
2{
3  byte data[8] = {a, b, c, d, e, f, g, h};
4  byte sndStat = CAN0.sendMsgBuf(txId*1000000+node_to*10000+msg_type*1000+dev_num*100+dev_type, 1, 8, data);  // send data:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
5//  byte sndStat2 = CAN0.sendMsgBuf(0x40000111, 8, data); //txBuf
6  if(sndStat == !CAN_OK){ Serial.print("MSG send error!"); }
7  //delay (310);
8}

 в качестве параметров этой функции ты передаешь переменные типа флоат (а,b,c,d,e,f,h). А потом создаёшь массив  уже типа byte 

и запихиваешь туда эти float, зачем так делать? Если действительно нужно передать float (он занимает в памяти МК 4 байта), то тебе придётся использовать для этого 4 байта поля данных CAN фрейма на каждый float , т.е. a,b,c,d. предварительно например , разбив float на 4 отдельные байта.

а если не надо float, то и нафиг в качестве параметров функции его использовать, если всё равно ты их в массиве byte data[8] к типу byte переводишь. Бери везде тип byte и иcпользуй.

Нельзя так к памяти МК относится, это я уже давно понял. 

 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

riv пишет:

Я вроде с этим тыкался, но для отладки быстрее выводиь все что пришло в сериал, а там опять преобразования.

вот это не понял немного. Какие преобразования. Для отладки я использую CAN сниффер. Мне почему удобнее работать с HEX, так как все анализаторы CAN шины выводят инфу в HEX и визуально уже привыкаешь все адреса и байты видеть в HEX. А без анализаторы шины при построении тайой системы я вообще не знаю как можно обойтись. Я почему в своей 11битной схеме ID  и отказался от 5 битных адресов, потому как их визуально мониторить вообще проблема. Хотя так было бы 32 адреса, а не 16. 

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

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

Я конечно тоже далекооо не крутой программист, вернее вообще не программист

Нельзя так к памяти МК относится, это я уже давно понял.

Я же говорю это был концепт, за выходные накидать, проверить что работает и вперед. Поэтому раньше и не выкладывал это позорище ;-)

Сейчас скинул чтобы идею обмена, работающую показать. Где то в коде вроде даже чтото с датчиками есть.

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:
Анализатора нет, подумаю на тему купить. Использовал прямой вывод всего что есть в сериал.

не надо покупать, делается за 5 мин

MaksVV
Offline
Зарегистрирован: 06.08.2015

смотри мой скетч #195, как я разряды вытягивал из переменной заголовка ID , там библиотека только не как у тебя, попроще она. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот по твоей теме вытянул в переменные byte разряды из 29-битного ID заголовка. Без всяких стрингов. Тип сообщения уже поставил на первый разряд

01void RX()
02{
03  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
04  {
05    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
06     
07     byte z,xx,yy,a,cc;
08 
09z  = (rxId & 0xF0000000)>>28;
10xx = (rxId & 0xFF00000)>>20;
11yy = (rxId & 0xFF000)>>12;
12a  = (rxId & 0xF00)>>8;
13cc = (rxId & 0xFF);
14  
15Serial.print(" CAN_ID  ");
16Serial.print(xx); //если нужно в НЕХ выводить в монитор просто пишешь так Serial.print(xx, HEX);
17Serial.print(" ");
18Serial.print(yy);
19Serial.print(" ");
20Serial.print(z);
21Serial.print(" ");
22Serial.print(a);
23Serial.print(" ");
24Serial.print(cc);
25Serial.print(" ");
26Serial.println();
27  }
28 
29if (z==1){ // если тип сообщения: "1"
30  // тогда что-нибудь тут сделаем и т.д.
31   
32  }
33 
34   
35}

 

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

а вот как обратно запихать в txId необходимые разряды: 

01unsigned long txId = 0x1ABCDEF2; // допустим был такой ID
02 
03//ниже, например, пусть будут у нас такие разряды
04byte z =  0x05;
05byte xx = 0xDD;
06byte yy=  0xEE;
07byte a =  0xB ;
08byte cc = 0xCC;
09 
10 
11void setup() {
12 
13Serial.begin (9600);
14Serial.print ("Old ID:                ");
15Serial.println (txId, HEX);
16 
17 
18// ниже вобъём наши разряды по одному в существующий ID, не задевая остальные разряды
19 
20Serial.println ("z=5, xx=DD, yy=EE, a=B, cc=CC");
21 
22txId = (txId & 0x0FFFFFFF)| (z & 0x0FFFFFFF)<<28; // вбиваем в ID разряд z, не трогая остальное
23 
24Serial.print ("New ID +z:             ");
25Serial.println (txId, HEX);
26 
27txId = (txId & 0xF00FFFFF)| (xx & 0xF00FFFFF)<<20; // вбиваем в ID разряд xx, не трогая остальное
28 
29Serial.print ("New ID +z,xx:          ");
30Serial.println (txId, HEX);
31 
32txId = (txId & 0xFFF00FFF)| (yy & 0xFFF00FFF)<<12; // вбиваем в ID разряд xx, не трогая остальное
33 
34Serial.print ("New ID +z,xx,yy:       ");
35Serial.println (txId, HEX);
36 
37txId = (txId & 0xFFFFF0FF)| (a & 0xFFFFF0FF)<<8; // вбиваем в ID разряд a, не трогая остальное
38 
39Serial.print ("New ID +z,xx,yy,a:     ");
40Serial.println (txId, HEX);
41 
42txId = (txId & 0xFFFFFF00)| cc;                  // вбиваем в ID разряд cc, не трогая остальное
43 
44Serial.print ("New ID +z,xx,yy,a,cc:  ");
45Serial.println (txId, HEX);
46 
47 
48   
49}
50 
51void loop() {
52  
53 
54}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

MaksVV пишет:
самый первый разряд в ID тот который ХХ, имеет не весь диапазон адресов ( не 256) , т.к первый ниббл Х может принимать значения только от 0 до 7. Потому что ID 29 бит, а не 32. Т.е на этот ниббл Х отводится 3 бита вместо четырех.

Сейчас подсчитал - что-то я напутал. Это в 11-битном ID на первый разряд 3 бита отводится (от 0 до 7), а в 29-битном на первый разряд отводится 1 бит, т.е. значения может принимать только 0 или 1. Поэтому нельзя туда тип сообщения вешать, придётся тебе жертвовать нибблом a device address. и вместо него этот тип сообщения z ставить. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

И я , наконец, разобрался почему ничего не получалось у меня с 29-битными ID. При опробовании этих 29бит наложилось несколько косяков - это нерабочий CAN модуль и плюсом к этому, я в обоих библиотеках (пробовал и твою и мою) просто неправильно отправлял расширенные ID. Поэтому толком не приходили эти 29битные ID и не отправлялись. Теперь разобрался с обоими библиотеками, как отправлять расширенные ID. 

В твоей библиотеке нужно в единичку ставить этот бит - выделен жирным (если он будет 0 то это 11бит) при отправке: 

 CAN0.sendMsgBuf(0x12345678, , 8, stmp);

А в моей библиотеке будет так:

1mcp2515.sendMessage(&canMsg2); // это отправка стандартного фрейма 11 бит
2mcp2515.sendMessage(MCP2515::TXB1,&canMsg1); // а вот так нужно отправлять фреймы с 29-битным ID

Единственное, для того, чтобы значение первого разряда в моей библиотеке (<mcp2515.h>) было равно 1, нужно отправлять 9

и соответственно чтобы было равно 0 - нужно отправлять 8 . Такова особенность библиотеки видимо. 

Пример. Для отправки ID 0х0aabbccd нам нужно отправить 0х8aabbccd

             Для отправки ID 0х1aabbccd нам нужно отправить 0х9aabbccd

И анализатор шины всё видит как надо. В общем я тоже перейду на 29 бит и будет 255 адресов для МК, работающих на одной шине.  

 

 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

Сейчас подсчитал - что-то я напутал. Это в 11-битном ID на первый разряд 3 бита отводится (от 0 до 7), а в 29-битном на первый разряд отводится 1 бит, т.е. значения может принимать только 0 или 1. Поэтому нельзя туда тип сообщения вешать, придётся тебе жертвовать нибблом a device address. и вместо него этот тип сообщения z ставить. 

По моему с твоей помощью вообще ничем жертвовать не придется. 29 бит это всего на 3 бита меньше чем IP адрес, и на всеь интернет числа хостов хватает.

Смотри если работать по битам то получаем при той же концепции следующее:

Это десятичная система, не вроде 16 ричная ;-)

//ID structure   xx.yy.z.a.cc
//      xx               yy                                z             a                        cc
//  my address   remote address    type message  device address     device type 
 
Это двоичная
//ID structure   
//   0000 0000      0000 0000         0000 0000        0000 0000         0000 0
//    0-255             0-255                   0-255             0-255                 0-31
//  my address   remote address    type message  device address     device type 
 
Можно даже подумать о изменении. C адресами ладно пусть в сети до 256 устройств, типов сообщений 32 а не 256 (и так перебор, можно 16, ну да ладно), адресов устройств 64 или 128 (больше на ардуине GPIO не бывает пока, а адрес устройства это номер pin на хосте т.е конкретном контроллере у которого свой адрес, типов устройств можно наоборот увеличить 512 или 1024
итого
 
//ID structure   
//   0000 0000      0000 0000            0000 0        0000 000             0000 0000 0
//    0-255             0-255                   0-31             0-127                 0-1023
//  my address   remote address    type message  device address     device type 
Как то так.
Что скажешь?
riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

А в моей библиотеке будет так:

1mcp2515.sendMessage(&canMsg2); // это отправка стандартного фрейма 11 бит
2mcp2515.sendMessage(MCP2515::TXB1,&canMsg1); // а вот так нужно отправлять фреймы с 29-битным ID

Кинь сылку на свою библиотеку. Может на одной либе начать работать, мне в принципе пока все равно. Я на этапе концепта.

Да и вообще может есть смысл начать плавно объединять усилия. Я сейчас в течении месяца ремонт завершу и займусь активнее разработкой. Мы вроде практически единстренные на форуме из любителей (имею ввиду не зарабатывающих на УД) в CAN двинули, всех 485 устраивает. 

Что я хочу получить на выходе ты увидел на схеме.

Так же хочу сделать аппаратную систему зоновой трансляции. Много аппаратных источников аудио (FM, USB MP3/SD MP3/AUX на УД/Bluetooth/AUX IP радио етс. Делать все буду на аудиопроцах или готовых модулях упр. по i2c (PT2314 TDA7419 или TEA6420)

Я из щита в каждое помещение завел аудиокабель и поставил динамик.

Ну а потом и мультирум.

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

 
Это двоичная
//ID structure   
//   0000 0000      0000 0000         0000 0000        0000 0000         0000 0
//    0-255             0-255                   0-255             0-255                 0-31
//  my address   remote address    type message  device address     device type 
 
 
//ID structure   
//   0000 0000      0000 0000            0000 0        0000 000             0000 0000 0
//    0-255             0-255                   0-31             0-127                 0-1023
//  my address   remote address    type message  device address     device type 
Как то так.
Что скажешь?

эмм. не понял откуда ты столько бит взял? тут же больше 29 (посчитай нолики)

по моим подсчетам вот так изначально у тебя затевалось:

//ID structure   
//   0000 0000      0000 0000             0000            0000               0000 0000  // итого 32 нолика многовато для CAN
//    0-255             0-255                   0-15             0-15                  0-255
//  my address   remote address    type message  device address   device type 
 
а по факту вот так выходит (переставим в начало как я хотел type message)
 
//ID structure   
//       0                       0000 0000      0000 0000              0000              0000 0000   // итого 29 ноликов
//      0-1                        0-255             0-255                  0-15                 0-255
//type message           my address   remote address     device address     device type 

как видим на type message что то мало значений приходится))

 

предлагаю убрать device address (ну засунешь его в тело сообщения, это ничего не меняет)

и делить разряды кратно 4 битам, т.е. нибблам. Поверь, это важно при отладке визуально в кан анализаторе. К тому же вытягивать числа из ID не кратные 4 битам вообще жопа (см. на предыдущей странице как я делал 5-битные адреса). В итоге предлагаю сделать так: 

 //ID structure   

//       0               0000           0000 0000       0000 0000       0000 0000   // итого 29 ноликов
//      0-1             0-15               0-255             0-255               0-255
//    no use    type message    my address   remote address    device type 
MaksVV
Offline
Зарегистрирован: 06.08.2015

моя библиотека, она работает не используя контакт INT CAN модуля. Что наверное плохо. Хотя ничто не мешает нам самим добавить сюда этот сигнал. (а в твоей либе походу без INT никак).  Просто я, дурень, не подключил этот контакт в МК_свет, а сейчас опять щит вскрывать влом. Но вроде работает пока c моей либой без INT вообще гуд. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вместе всегда проще, конечно. А то я тут один долго демагогию по кану разводил))

1/device type
2//Sensor
3uint32_t  air_temp_cens = 1;
4uint32_t  air_hum_cens = 2;
5uint32_t  air_pres_cens = 3; //и т.д.

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

1/device type
2//Sensor
3#define  AIR_TEMP_CENS  1
4#define  AIR_HUM_CENS    2
5#define  AIR_PRES_CENS  3
6и т.д.

в принципе стратегия CAN шины такая (я тут недавно тоже рассказывал одному человеку про CAN):

я думаю тебе стоит к ней подтягиваться т.к. у меня уже реально неделю работает, сбоев нет. В скетче #195 вобщем-то всё подробно прокомментировано. 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

моя библиотека

Ок. Готов пользовать ее, единственое что меня смущает что ее доработка остановилась, а coryjfowler либу дорабатывает. Ну да и ладно. Работает и работает. 

MaksVV пишет:

это предлагаю не заводить на переменные, а просто задефайнить.

Ок.

MaksVV пишет:

МК нижний от верхнего получает инфу о состоянии включенности света в комнатах, движении в комнатах, пож.датчиков. ...

Я бы еще добавил правил

1. Информация с датчиков (оконечных МК) передается центральному МК 

1.1 при включении

1.2 при изменении параметров более чем на 5% для дискретных и при изменении значения для булевых

1.3 периодически (1 раз в 600 секунд например)

1.4 при опросе из центра

2. Работа с исполнительными устройствами

При отправке команды исполнительному у-ву булевому, дискретному, временному ждем квитирование принятия команды к исполнению + ждем отчета о исполнении. Вся логика работы к исполнителным у-вом как и с датчиком лежит в оконечном МК, центр должен работать со всеми датчиками и ИУ абстрагировано, выдал команду получил отчет.

3. Все оконечные МК периодически сообщают центральному что живы, если не живы получают ресет например по питанию.

4. Резервирование

Центральных контроллеров 2 и они имеют одинаковый код за исключением вставки Master-Slave

Slave передает периодически в сторону мастера свое состояние  и опрашивает состояние мастера. Если мастер отказал, Slave берет управлени на себя рассылая по сети сообщение что он мастер (по оконечным меняем глобальную переменную адреса с 1 на 2)

Master если оживает в первую очередь шлет запрос Slave  не мастер ли он, меняет ему статус на Slave, делает рассылку оконечным на смену мастера.

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:
2. Работа с исполнительными устройствами

При отправке команды исполнительному у-ву булевому, дискретному, временному ждем квитирование принятия команды к исполнению + ждем отчета о исполнении. Вся логика работы к исполнителным у-вом как и с датчиком лежит в оконечном МК, центр должен работать со всеми датчиками и ИУ абстрагировано, выдал команду получил отчет.

вот тут непонятно, если CAN упадёт, как будут себя вести локальные МК, типа переходить в автономный режим работы? С остальными дополнениями в принципе согласен. 

Эх, как бы это ещё всё запрограммировать . И что со структурой ID, согласен с предложенным мной вариантом?

MaksVV
Offline
Зарегистрирован: 06.08.2015

del

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

вот тут непонятно, если CAN упадёт, как будут себя вести локальные МК, типа переходить в автономный режим работы? С остальными дополнениями в принципе согласен. 

Да, с минимальным функционалом по жесткому алгоритму (Переход с ДУ на МУ) , хотя я бы просто переводил в режим ожидания.

MaksVV пишет:

Эх, как бы это ещё всё запрограммировать .

Ну дорогу осилит идущий ;-)

MaksVV пишет:

И что со структурой ID, согласен с предложенным мной вариантом?

Извини может я туплю можещь ее формализовать и выложить сюда в формате xyz ?

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

Извини может я туплю можещь ее формализовать и выложить сюда в формате xyz ?


Читай сообщение #225. Там я предложил в твоем формате, только без adress device

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:
riv пишет:

Извини может я туплю можещь ее формализовать и выложить сюда в формате xyz ?

Читай сообщение #225. Там я предложил в твоем формате, только без adress device

Вот я и говорю что ступил, простто пропустил сообщение.

riv
Offline
Зарегистрирован: 20.07.2017

Я пока формулирую концепцию для обсуждения,  ведь мы по сути делем протокол overCAN для роботы сети MK.

Просмотри коротко что придумали до нас не глупые люди, думаю стоит идей от туда надергать, но без фанатизма

Есть три протокола over CAN

— CANopen (CANFestival)  

http://can.marathon.ru/page/can-protocols/canopen

https://habrahabr.ru/post/144435/  

http://we.easyelectronics.ru/STM32/can-canopen-canfestival-stm32-chast-pervaya.html

— DeviceNet

http://can.marathon.ru/page/can-protocols/devicenet/devicenetintro

— CAN Kingdom

https://habrahabr.ru/post/275895/

Не забывай про протоколы верхнего уровня

  • MQTT: протокол для сбора данных устройств и передачи их серверам (D2S);
  • XMPP: протокол для соединения устройств с людьми, частный случай D2S-схемы, когда люди соединяются с серверами;
  • DDS: быстрая шина для интегрирования интеллектуальных устройств (D2D);
  • AMQP: система организация очередей для соединения серверов между собой (S2S).

(Вот тут почитай http://www.rtsoft.ru/press/articles/detail.php?ID=2718)

Протокол MQTT https://ipc2u.ru/articles/prostye-resheniya/chto-takoe-mqtt/ с которым хочешь не хочешь придется считаться т.к. на нем практически все opensourser сервера УД живут.

riv
Offline
Зарегистрирован: 20.07.2017

И работа с ниблами просто ресурс адресации сжигает. По рукам и ногам вяжет. Весь интернет на 32 витах адресуется а мы из-за ниблов не модем 256 GPIO адесовать. Может другой путь обдумать. Потом локти кусать будем.

MaksVV
Offline
Зарегистрирован: 06.08.2015

почитал бегло, есть над чем задуматься. Не охото велосипед изобретать. Надо более подробно почитать. Инфа полезная. 

riv
Offline
Зарегистрирован: 20.07.2017

И ты только не бросайся в меня чем не попадя, мне удалось нормально https://github.com/jgeisler0303/CANFestivino собрать

MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

И работа с ниблами просто ресурс адресации сжигает. По рукам и ногам вяжет. Весь интернет на 32 витах адресуется а мы из-за ниблов не модем 256 GPIO адесовать. Может другой путь обдумать. Потом локти кусать будем.

Не очень понял про какие нибблы речь. Ниббл всего один используется в предложенном мной варианте - это type message, 16 значений разве не хватит?

Я чесно использовал в предложенном варианте 28 бит из 29. А больше 29бит то ведь низя! Не влезает сюда этот device address. 

А если значений device type мало. Ну давай оставшийся неиспользуемый бит прилепим к байту типа девайса и будет тебе не 256 типов устройств, а 512. 

Ещё раз предложенный вариант 

//ID structure   

//       0               0000           0000 0000       0000 0000       0000 0000   // итого 29 бит (показаны нолями)
//      0-1             0-15               0-255             0-255               0-255
//    no use    type message    my address   remote address    device type 
MaksVV
Offline
Зарегистрирован: 06.08.2015

riv пишет:

И ты только не бросайся в меня чем не попадя, мне удалось нормально https://github.com/jgeisler0303/CANFestivino собрать

блин, вообще нифига не понятно))

тебе конечно попроще оперировать всеми этими понятиями. Я так понял, ты варишься частенько в этом всём. В материале так сказать  - топологии, всякие верхние уровни. 

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

riv
Offline
Зарегистрирован: 20.07.2017

Давай пойдем от задач. Совсем сверху.

1. Есть дом/квартира с n помещений в которых есть датчики и исполнительные устройства (ИУ) и вкоторые из центра идут кабели или радиоканалы. (Перечень датчиков и исполнительных устройств см. на моей схеме)

2. Есть оконечные контроллеры которые являются концентраторами датчиков и ИУ, принимают от них данные передают наверх и получают команды сверху. В общем случае просто расширители от центра. Есть исключения например система защиты от протечек у нее 2 жестких сценария, либо закрыть краны от датчиков либо по команде от центра + сервичные провороты кранов. Управление котлом например. И прочие узкие задачи.

3. Есть центр сосредоточния кабелей т.е. ядро сети от куда будем всем управлять по более сложным но все равно фиксированным сценариям. И откуда работает автоматика-автоматизация по простым алгоритмам ( есть движение зажгли свет, стало жарко включили кондиционер, холодно котел или электрорадиатор, стало много со2 включили рекуператор и т.д)

4. Есть сервер УД который дает возможность визуализации всех событий от датчиков, ИУ и самое главное дает возможность создавать сложные сценарии. Например зимой теплее холоднее это задвижки на радиаторах а летом кондиционер и пр. Режимы освещения и пр. Т.е он через Web например позволяет задать контроллерам параметры для изменения алгоритмов. 

Отсюда требования к системе.

1. Потеря контроллера (поломка) не приводит к аварии в доме. Это как раз достигается запаралеливанием управления от МК и от клавиш, кнопок, тумблеров пультов. Т.е мы просто делаем дистанционное управление устройствами и снятие показаний но не убираем возможность управлять в ручную. Например если МК защиты от протечек умрет я не останусь без воды, если МК света то буду выключателями включать и т.д

2. Должны быть заданы минимальные управляющие алгоритмы абстрагирующие нас и верхний уровень от взаимодействия с датчиком или ИУ. Т.е запросил температуру получил значение. Дал команду зажечь свет, он зажегся и получено подтверждение что он зажегся. Независимо как мы его зажигаем. Могут быть разные типы управления светом дискретные если диммер или булевы если реле.

....

Завтра допишу.  

 

riv
Offline
Зарегистрирован: 20.07.2017

Перебрал все варианты, решил остановиться на твоем, с небольшим изменением

//ID structure   x.y.z.aa.bb
//      X            Y               AA              BB                              CC         
//  direction  type message     node address   remote node address      remote node sensor/device  type 
Набросал немного кода, посмотри если несложно.
Уткнулся в кодирование CAN ID из значений ENUM
01long unsigned int Code_can_id_msg(uint8_t direction,uint8_t msg_type,uint8_t dev_addr,uint8_t rem_addr,int8_t  dev_type)
02{
03long unsigned int can_id_msg;
04 
05Serial.print("TX Direction " );Serial.println(direction);
06Serial.print("TX Comm_type " );Serial.println(msg_type);
07Serial.print("TX Node addr " );Serial.println(dev_addr);
08Serial.print("TX Rem addr" );Serial.println(rem_addr);
09Serial.print("TX Dev type " );Serial.println(dev_type);
10 
11///can_id_msg=???????????????; Как собрать uint8_t в long unsigned int сохранив структуру байтов??????????
12Serial.print("TX CAN ID " );Serial.println(can_id_msg, HEX);
13return can_id_msg;
14}

Подскажи Как собрать uint8_t в long unsigned int сохранив структуру байтов CAN ID?

 

 
MaksVV
Offline
Зарегистрирован: 06.08.2015

MaksVV пишет:

Я чесно использовал в предложенном варианте 28 бит из 29. А больше 29бит то ведь низя! Не влезает сюда этот device address. 

А если значений device type мало. Ну давай оставшийся неиспользуемый бит прилепим к байту типа девайса и будет тебе не 256 типов устройств, а 512. 

Ещё раз предложенный вариант 

//ID structure   

//       0               0000           0000 0000       0000 0000       0000 0000   // итого 29 бит (показаны нолями)
//      0-1             0-15               0-255             0-255               0-255
//    no use    type message    my address   remote address    device type 

вот как будет выглядеть на практике работа с разрядами, если сделать device type 9-битным (512 значений).

01unsigned long ID = 0x1CCDDBBE; // допустим получили из CAN такой ID
02 
03uint16_t  device_adress;  // в эту переменную запишем самый старший 9-битный разряд из ID (1СС)
04 
05uint16_t  device_adressNEW = 510; // а потом обратно, в старший разряд ID запишем этот адрес (в HEX это 1FE)
06 
07void setup() {
08 
09Serial.begin (9600);
10 
11device_adress = (ID & 0xFFF00000)>>20;  // вытянем из старшего разряда ID-заголовка 9-битный device type
12  
13Serial.println (device_adress, HEX);
14 
15 
16// и обратно - запихаем в старший разряд ID-заголовока переменную  device_adressNEW:
17ID = (ID & 0x000FFFFF) | (device_adressNEW & 0x000FFFFF)<<20;
18 
19 
20Serial.println (ID, HEX);
21 
22}
23 
24void loop() {}

 

riv
Offline
Зарегистрирован: 20.07.2017

MaksVV пишет:

//ID structure   

//       0               0000           0000 0000       0000 0000       0000 0000   // итого 29 бит (показаны нолями)
//      0-1             0-15               0-255             0-255               0-255
//    no use    type message    my address   remote address    device type 

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

//       0               0000           0000 0000       0000 0000       0000 0000   // итого 29 бит (показаны нолями)
//      0-1             0-15               0-255             0-255               0-255
//    direction    type message    my address   remote address    device type 
 
512 бит не нужно,  хватит 256.
riv
Offline
Зарегистрирован: 20.07.2017

Del

riv
Offline
Зарегистрирован: 20.07.2017

Спасибо, в твоем примере нашел.

can_id_msg=(direction & 0xFFFFFFFF)<<28 | (msg_type & 0x0FFFFFFF)<<24 | (dev_addr & 0x00FFFFFF)<<16 | (rem_addr & 0x0000FFFF)<<8 | (dev_type & 0x000000FF);

Гдеб об этом почитать, а то как сапер примеры разбираю.

MaksVV
Offline
Зарегистрирован: 06.08.2015

 можно так

1can_id_msg= (direction & 0xFFFFFFFF)<<28 | (msg_type & 0xFFFFFFFF)<<24 | (dev_addr & 0xFFFFFFFF)<<16 | (rem_addr & 0xFFFFFFFF)<<8 | dev_type;

читать про побитовые операции. Я сам это плохо понимаю, так допёр опытным путём.  

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

а вот как парсить приходящий ID при таком твоём варианте

01unsigned long rxId = 0x1ABCDEF2; // допустим был такой ID
02 
03//ниже, например, пусть будут у нас такие разряды
04 
05bool direction;
06byte z;            // type message
07byte xx;           // my address
08byte yy;           // remote address
09byte cc;           // device type
10 
11 
12void setup() {
13 
14Serial.begin (9600);
15 
16 
17 
18direction  = (rxId & 0xF0000000)>>28;
19 
20z = (rxId & 0xF000000)>>24;
21 
22yy = (rxId & 0xFF0000)>>16;
23 
24xx  = (rxId & 0xFF00)>>8;
25 
26cc = (rxId & 0xFF);
27 
28 
29 
30Serial.print ("RX CAN_ID     "); Serial.println (rxId, HEX);
31 
32Serial.print("parse CAN_ID  ");
33 
34 
35Serial.print(direction, HEX);
36 
37Serial.print(" ");
38 
39Serial.print(z, HEX);
40 
41Serial.print(" ");
42 
43Serial.print(yy, HEX);
44 
45Serial.print(" ");
46 
47Serial.print(xx, HEX); //если нужно в НЕХ выводить в монитор просто пишешь так Serial.print(xx, HEX);
48 
49Serial.print(" ");
50 
51Serial.print(cc, HEX);
52 
53Serial.print(" ");
54 
55Serial.println();
56 
57 
58   
59}
60 
61void loop() {}

 

riv
Offline
Зарегистрирован: 20.07.2017

Я вот так реализовал на своей библиотеке https://github.com/coryjfowler/MCP_CAN_lib

Это прием

01void RX()
02{
03  uint8_t direction, msg_type, dev_addr, rem_addr, dev_type;
04  uint8_t data_b0,data_b1,data_b2,data_b3,data_b4,data_b5,data_b6,data_b7;
05  if(!digitalRead(CAN0_INT))                         //
06  {
07    CAN0.readMsgBuf(&rxId_can, &len_can, rxBuf_can);      // Read data: len = data length, buf = data byte(s)
08 
09    direction  = (rxId_can & 0x10000000)>>28;   //  извлекаем 1-битный идентификатор запроса-ответа из ID
10    msg_type = (rxId_can &   0x0F000000)>>24; //    извлекаем 4-битный идентификатор сообщения из ID 
11    dev_addr  = (rxId_can &  0x00FF0000)>>16;   //  извлекаем 8-битный адрес отправителя из ID
12    rem_addr = (rxId_can &   0x0000FF00)>>8; //     извлекаем 8-битный адрес получателя из ID
13    dev_type = (rxId_can &   0x000000FF); //        извлекаем 8-битный тип устройства у получателя из ID
14    /*data_b0 = rxBuf_can[0]&0xFF;
15    data_b1 = rxBuf_can[1]&0xFF;
16    data_b2 = rxBuf_can[2]&0xFF;
17    data_b3 = rxBuf_can[3]&0xFF;
18    data_b4 = rxBuf_can[4]&0xFF;
19    data_b5 = rxBuf_can[5]&0xFF;
20    data_b6 = rxBuf_can[6]&0xFF;
21    data_b7 = rxBuf_can[7]&0xFF;*/
22    DeCode_can_id_msg(direction,msg_type,dev_addr,rem_addr,dev_type,rxBuf_can);
23  }
24}

Это декодирование

01void DeCode_can_id_msg(uint8_t direction,uint8_t msg_type,uint8_t dev_addr,uint8_t rem_addr,int8_t  dev_type,byte rxBuf_can)
02{
03//Декодируем направление сообщения запрос-ответ
04if (direction==0)
05{
06  Serial.print("RX Reqv");
07}
08else if (direction==1)
09{
10  Serial.print("RX Ansv");
11}
12//Декодируем тип сообщения
13    int i = 0;
14    int table_size;
15    table_size = sizeof(Message_CANData)/sizeof(Message_CANvalueData);
16  for (i = 0; i < table_size; i++)
17  {
18    if (Message_CANData[i].msg_num == msg_type)
19    {
20      Serial.print(" type_msg - ");
21      Serial.print(Message_CANData[i].msg_name);
22    }
23   }
24//Декодируем адрес отправителя
25i = 0;
26    table_size = sizeof(Node_addr_CANData)/sizeof(Node_addr_CANvalueData);
27  for (i = 0; i < table_size; i++)
28  {
29    if (Node_addr_CANData[i].node_num == dev_addr)
30    {
31      Serial.print(" node_addr - ");
32      Serial.print(Node_addr_CANData[i].node_name);
33    }
34   }
35//Декодируем адрес получателя
36i = 0;
37    table_size = sizeof(Node_addr_CANData)/sizeof(Node_addr_CANvalueData);
38  for (i = 0; i < table_size; i++)
39  {
40 
41    if (Node_addr_CANData[i].node_num == rem_addr)
42    {
43      Serial.print(" Rem_addr - ");
44      Serial.print(Node_addr_CANData[i].node_name);
45 
46    }
47   }
48//Декодируем тип устройства
49i = 0;
50    table_size = sizeof(sens_dev_CANData)/sizeof(sens_dev_CANvalueData);
51  for (i = 0; i < table_size; i++)
52  {
53    if (sens_dev_CANData[i].dev_num == dev_type)
54    {
55      Serial.print(" Dev_type - ");
56      Serial.print(sens_dev_CANData[i].dev_name);
57      Serial.print("\n");
58    }
59   }
60 
61}

Это передача

01void TX(long unsigned int txId_can, int can_msg_type, int can_type_id, byte data[8])
02{
03  bool err = false;
04   
05  if (can_type_id == 29)
06  {
07    if (can_msg_type==0)
08    {
09 
10      byte sndStat = CAN0.sendMsgBuf(txId_can, 1, 8, data);  //send NORMAL EXTERNAL ID
11      if(sndStat == CAN_OK){err=false;} else {err=true;}
12    } else if (can_msg_type==4)
13    {
14      txId_can=0x40000000;
15      byte sndStat = CAN0.sendMsgBuf(txId_can, 8, data); //send REMOTE REQUEST FRAME
16      if(sndStat == CAN_OK){err=false;} else {err=true;}
17    }
18    else if (can_msg_type==8)
19    {
20      byte sndStat = CAN0.sendMsgBuf(txId_can,1 ,8, data); //send NORMAL EXTERNAL ID
21      if(sndStat == CAN_OK){err=false;} else {err=true;}
22    }
23  } else if (can_type_id == 11)
24    {
25    if (can_msg_type==0)
26    {
27      byte sndStat = CAN0.sendMsgBuf(txId_can, 0, 8, data); ////send NORMAL STANDART ID
28      if(sndStat == CAN_OK){err=false;} else {err=true;}
29    } else if (can_msg_type==4)
30    {
31      txId_can = 0x40000000; // send REMOTE REQUEST FRAME
32      byte sndStat = CAN0.sendMsgBuf(txId_can, 8, data);
33      if(sndStat == CAN_OK){err=false;} else {err=true;}
34    } else if (can_msg_type==8)
35    {
36      txId_can = txId_can+0x80000000; //0x80000000 переводит в расширенный, без нее стандартный
37      byte sndStat = CAN0.sendMsgBuf(txId_can, 8, data);
38      if(sndStat == CAN_OK){err=false;} else {err=true;}
39    }     
40    }
41         
42    //delay(100);   // send data per 100ms   
43      if(err == false){
44      //Serial.println("Message Sent Successfully!");
45      } else {
46      Serial.println("Error Sending Message...");
47    }
48}

 

 
Это кодирование
 
1long unsigned int Code_can_id_msg(uint8_t direction,uint8_t msg_type,uint8_t dev_addr,uint8_t rem_addr,int8_t  dev_type)
2{
3long unsigned int can_id_msg;
4 
5can_id_msg=(direction & 0xFFFFFFFF)<<28 | (msg_type & 0x0FFFFFFF)<<24 | (dev_addr & 0x00FFFFFF)<<16 | (rem_addr & 0x0000FFFF)<<8 | (dev_type & 0x000000FF);
6Serial.print("TX CAN ID " );Serial.println(can_id_msg, HEX);
7return can_id_msg;
8}

 

 
Ну а это вызов
 
1TX(Code_can_id_msg(1, COMMAND_SEND, node_address, Hallway_net_center,air_h_s),0,29,data);
 
Так вызываем при ручной передае параметров
 
1TX(0x02222222,8,29,data);

Декодирую через структуру, кодирую через перечисление

01// Задаем перечисления и структуры для типов сообщений Y
02typedef enum Message_enum
03{
04    NULL_C,                //0
05    COMMAND_SEND,          //1
06    COMMAND_ANSVER,        //2
07    REQUEST_SEND,          //3
08    REQUEST_ANSVER,        //4
09    STATUS_REQUEST_SEND,   //5
10    STATUS_REQUEST_ANSVER  //6
11                    
12} Message_CAN_ENUM;              
13 
14typedef struct {
15    uint8_t          msg_num;
16    String           msg_name;
17}Message_CANvalueData;
18 
19const Message_CANvalueData Message_CANData[] =
20{
21        /*Key        KeyName */
22        { 0 ,    "NULL_C"},
23        { 1 ,    "COMMAND SEND"},
24        { 2 ,    "COMMAND_ANSVER"}, 
25        { 3 ,    "REQUEST_SEND"},
26        { 4 ,    "REQUEST_ANSVER"},
27        { 5 ,    "STATUS_REQUEST_SEND"},
28        { 6 ,    "STATUS_REQUEST_ANSVER"}
29 
30};

 

 
riv
Offline
Зарегистрирован: 20.07.2017

Тут еще оказалось, что у меня товарищ делает overCAN протокол для управления набором модулей , правда он на 11 битном (2.0а) но тоже есть интересные идеи. В наш протокол особо нужные идеи перенесу.

1. Идея это обязательно иметь уникальный номер сообщения, у контроллера, я его в блок данных внесу, крутится счетчик в рамках выделенных бит с сбросом в о после переполнения.

2. Ну это как в CAN Open возможность передачи не только Короткий – любые сообщения длиной до 8 байт  но и Составной кадр – любые сообщения длиной более 8 байт.

3. Типы сообщений

Команда управления - сообщение в адрес узла 

Команда-Запрос  - сообщение в адрес узла  с запросом выдачи информации о состоянии

Команда контроля 

Технологическая команда 

Ответное сообщение - ответ от узла 

Инициативное сообщение – сообщение узла , выдаваемое в инициативном порядке.

riv
Offline
Зарегистрирован: 20.07.2017

В общем обмен написал, сечас подумаю на тему структуры протокола. Выложу сюда. Пока смотри node1.int https://yadi.sk/d/7pyVRdHJ3TNYXr