Перейти к содержанию

Опросить слейвы по CAN.

Есть мастер и три слейва. У каждого слейва три параметра. Мне нужно за один опрос взять все три параметра с каждого слейва.
То есть для принятия решения мне нужно все 9 параметров. Потом я делаю свои дела и потом делаю новый опрос слейвов.
Вопрос как знать что все слейвы ответили именно на этот опрос? Есть какое то красивое решение или как всегда обычно?
Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Jenya7 @ Feb 7 2018, 09:20) <{POST_SNAPBACK}>
Вопрос как знать что все слейвы ответили именно на этот опрос?

Добавить в пакеты поле "идентификатор запроса".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Что изменится, если все условные Slave будут постоянно вещать в шину, а условный Master когда ему угодно будет принимать посылки? Точно нужна система запрос-ответ?

В одном из оборудований Bosch встречался вариант, когда в посылке из 8 байт последний отводился под номер посылки, от 0 до 255 и далее по кругу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Допустим при посылке вместе с данными я буду посылать номер опроса.
А при приеме если пришел тот же номер опроса выставлять флаг на каждый параметер.
Код
uint32_t CAN_GetMessage(void)
{
    uint32_t mot_idx;
    uint32_t opcode;
    uint32_t message_num;
    
    uint8_t position;
  
    CAN_Receive(CAN1, can_params.fifo_num,  &RxMessage);
    
    mot_idx = (RxMessage.StdId >> 8);
    
    opcode = (RxMessage.StdId - (mot_idx * 0x100));
          
    switch (opcode)
    {      
        case CAN_COM_IGET:
            motor_data[mot_idx].current = (RxMessage.Data[3]<<24) | (RxMessage.Data[2]<<16) |
                                          (RxMessage.Data[1]<<8)  | RxMessage.Data[0];
            position = CAN_IGET_POS;
        break;
        
        case CAN_COM_PGET:
            motor_data[mot_idx].position = (int32_t)((RxMessage.Data[3]<<24) | (RxMessage.Data[2]<<16) |
                                           (RxMessage.Data[1]<<8)  | RxMessage.Data[0]);
            position = CAN_PGET_POS;
        break;
        
        case CAN_COM_SGET:
            motor_data[mot_idx].speed = (RxMessage.Data[3]<<24) | (RxMessage.Data[2]<<16) |
                                        (RxMessage.Data[1]<<8)  | RxMessage.Data[0];
            position = CAN_SGET_POS;
        break;
    }
    
    message_num = (RxMessage.Data[7]<<8) | RxMessage.Data[6];
    if (can_message_num == message_num)
    {
         motor_data[mot_idx].can_rx_flags |= (1<<position);
    }
  
     return CAN_OK;
}

и потом проверять
Код
uint32_t MOT_DataReady(void)
{
    int i;
    uint32_t resp = 0;
    
    //check if all motors replied
    for (i = 0; i < MAX_MOTORS; i++)
    {
        if (motor_data[i].ena)
        {
            if ((motor_data[i].can_rx_flags & 0x0F) == 0x0F)
                resp++;
        }      
    }
    
    //all motors responded with all data
    if (resp == g_motors_num)
    {
        //clear all flags - get ready for the next data request
        for (i = 0; i < MAX_MOTORS; i++)
        {
            if (motor_data[i].ena)
                motor_data[i].can_rx_flags = 0;  
        }
        //next data request number
        can_message_num++;
        return 1;
    }
    else
        return 0;
}

Возникает вопрос как ожидать получения всех данных? в while?
Код
while (!MOT_DataReady());

А если какой то слейв умер?
Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Тогда сработает таймаут и большими красными буквами будет написано

ВАШЕ УСТРОЙСТВО ... СДОХЛО И НЕ ОТВЕЧАЕТ !!!
ИЩИТЕ ПАЯЛЬНИК !!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(x893 @ Feb 7 2018, 12:34) <{POST_SNAPBACK}>
Тогда сработает таймаут и большими красными буквами будет написано

ВАШЕ УСТРОЙСТВО ... СДОХЛО И НЕ ОТВЕЧАЕТ !!!
ИЩИТЕ ПАЯЛЬНИК !!!

а когда начать новый опрос? тут есть проблема принятия решения.
Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Jenya7 @ Feb 7 2018, 10:40) <{POST_SNAPBACK}>
а когда начать новый опрос? тут есть проблема принятия решения.

У вас реалтайм-система или как?
Я делаю так как писали выше. Контроллеры сами с нужной частотой шлют данные.
Мастер пакеты получает и перезапускает таймеры для каждого слейва.
В любой момент мастер имеет информацию о "свежести" данных и может либо их использовать,
либо сигнализировать о потере связи со слейвом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(adnega @ Feb 7 2018, 13:30) <{POST_SNAPBACK}>
У вас реалтайм-система или как?
Я делаю так как писали выше. Контроллеры сами с нужной частотой шлют данные.
Мастер пакеты получает и перезапускает таймеры для каждого слейва.
В любой момент мастер имеет информацию о "свежести" данных и может либо их использовать,
либо сигнализировать о потере связи со слейвом.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Jenya7 @ Feb 7 2018, 11:47) <{POST_SNAPBACK}>
у меня слейвы не шлют данные сами по себе. они отвечают на запрос от мастера.

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

Цитата(Jenya7 @ Feb 7 2018, 11:47) <{POST_SNAPBACK}>
а зачем нужны таймеры для каждого слейва?

У меня каждое устройство (узел) раз в секунду шлет SYNC-пакет с идентификационной информацией.
Мастер (я его/их называю Сервером) получает все SYNC-пакеты, пересбрасывает таймеры в таблице узлов,
при необходимости добавляет новые узлы в таблицу узлов, генерит сообщения "пропала/восстановлена" связь с узлом.
Если таймер в таблице узлов досчитал до 10 секунд, то это означает, что узел не пресылает SYNC-пакеты уже 10 секунд, а значит его нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(adnega @ Feb 7 2018, 14:15) <{POST_SNAPBACK}>
Просто нужно понимать, что слейвы могут слать данные и без запроса.
Например, мастер может сказать слейву: шли такие-то данные с такой-то периодичностью столько-то раз.


У меня каждое устройство (узел) раз в секунду шлет SYNC-пакет с идентификационной информацией.
Мастер (я его/их называю Сервером) получает все SYNC-пакеты, пересбрасывает таймеры в таблице узлов,
при необходимости добавляет новые узлы в таблицу узлов, генерит сообщения "пропала/восстановлена" связь с узлом.
Если таймер в таблице узлов досчитал до 10 секунд, то это означает, что узел не пресылает SYNC-пакеты уже 10 секунд, а значит его нет.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
QUOTE (Jenya7 @ Feb 7 2018, 11:33) <{POST_SNAPBACK}>
нет. мне не нужно чтоб слейвы заваливали мастера данными когда не нужно. все четко - мастер послал запрос - получил ответ - принял решение на основе пришедших данных - послал следующий запрос.
Тогда зачем тут CAN? Потому что "стильно, модно, молодежно"? RS485 справился бы не хуже и дешевле. Изюминка CAN в том, что посылать могут все, при этом все смогут передать и конфликты будут разрешены на низком уровне в контроллере. Заложить в систему CAN и использовать его как RS485 по меньшей мере странно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Сергей Борщ @ Feb 7 2018, 14:58) <{POST_SNAPBACK}>
Тогда зачем тут CAN? Потому что "стильно, модно, молодежно"? RS485 справился бы не хуже и дешевле. Изюминка CAN в том, что посылать могут все, при этом все смогут передать и конфликты будут разрешены на низком уровне в контроллере. Заложить в систему CAN и использовать его как RS485 по меньшей мере странно.

но мне реально не нужно чтоб слейвы заплевывали меня данными когда их не просят. только потому что КАН позволяет это - давайте шлите - нам не жалко? и как в таком случае отследить что я получил полный набор данных от всех слейвов?
к тому же можно поставить фильтры и слейвы получат только свои сообщения, в RS485 нужно парсить самому.

да. помню был проект. 5 узлов. все слали всем, все прекрасно работало. но там каждая посылка содержала все в себе. это был отдельный обект. а мне нужно получить все посылки от всех обыектов и чтоб посылки были синхронизированные.
Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Так и не понял, в чем у ТС проблема?

Если хочется, чтобы было так, как сделано: CAN по опросу, то ваш мастер же знает, когда и кому он послал запрос.
Прошел установленный таймаут ответа, если есть желание, можно сделать еще одну-две попытки перезапроса,
если ответа нет - все, ошибка. Мигать красным фонарем и дудеть в пищалку.
При приходе времени очередного цикла опроса всех датчиков - попытаться опросить снова. Если все ответили - отбой тревоги, если нет, продолжаем мигать красным свистком. И далее по циклу.

Если сделать, как принято в CAN, когда датчики сами регулярно публикуют свои данные, то adnega тоже уже все подробно расписал: мастер все принимает, у него есть вся инфа, кто передал, когда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(adnega @ Feb 7 2018, 12:30) <{POST_SNAPBACK}>
У вас реалтайм-система или как?
Я делаю так как писали выше. Контроллеры сами с нужной частотой шлют данные.
. . .

Я только начал работать с CAN.
Вопрос из тойже оперы. У меня реалтайм система (управление 3 сервоприводами, скорость CAN 250kbit ).
Изначально так и заложено, каждый серво "отстреливает" 4 раза в секунду текущую координату положения.

Так или иначе, слейвы работают асинхронно по отношению друг к другу.
То что на шине не будет коллизий указано в стандарте на CAN.
т.е. все слейвы передадут свою инф., - рано или поздно.

? 1. Для такой схемы передачи инфорамции нужно самому планировать структуру трафика по CAN ?
(при большом кол-ве слейвов )

? 2. Обязательно ли в заголовках пакетов использовать биты приоритета ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация