Помогите с I2C

Тема в разделе "Raspberry Pi", создана пользователем Igor68, 29 июн 2016.

  1. Igor68

    Igor68 Гуру

    Запись в шилд по i2c получается - всё нормально! Но вот для чтения состояния к примеру значения АЦП и т.п. из шилда ума не приложу как.
    Например если читаю регистр - устройство (память):
    1 - Адрес устройства с флагом чтения и записи.
    2 - Адрес ячейки
    3 - данные (либо читаю либо записываю)
    тоже нет проблем при записи в шилд команды с параметрами:
    1 - адрес устройства
    2 - команда (например установить значения скорости двигателя(лей)
    3 - массив параметров(байты)
    Работает, а вот с шилдом для чтения параметров(состояния):
    1 - Адрес устройства
    2 - Код команды
    3 - параметр команды(битовая маска выбора списка параметра(ров)) для чтения
    4 - данные
    При записи на питоне:
    bus.write_i2c_block_data(addr, 3, [vh1, vl1, vh2, vl2, vh3, vl3, vh4, vl4] )
    всё понятно, но чтение:
    res = bus.read_i2c_block_data(addr,cmd,sz)
    где cmd - собственно команда (6 - чтение значения АЦП)
    sz - размер данных (6 байт, которые надо получить)
    куда прикрутить параметр команды?
    Куда копать? не обязательно на питоне можно на си.
    Заранее спасибо!
     
    Последнее редактирование: 30 июн 2016
  2. DIYMan

    DIYMan Guest

    Если навскидку (не знаю, как там функция объявлена), то как-то так:
    Код (C++):
    byte cmd[6] = {0};
    res = bus.read_i2c_block_data(addr,cmd,sizeof(cmd));
     
  3. Igor68

    Igor68 Гуру

    Насколько я понимаю - я это испытал ранее (питон):
    res = bus.read_i2c_block_data(0x06,0x06,0x06)
    посылаются 0x06(addr), 0x06(cmd); надо принять 6 байт.
    требуется послать 0x06(addr), 0x06(cmd), 0x04(bit_mask_type); и принять 6 байт.
    тоесть 0x06 (второй посылаемый - команда), после чего параметр команды 0x04 и только после получения параметра устройство соизволит ответить шестью байтами.
     
  4. DIYMan

    DIYMan Guest

    Ну так посылайте и принимайте, кто мешает-то? Не видя описания функций на С - ничем конкретно не помочь.
     
  5. Igor68

    Igor68 Гуру

    Простите это Python (и я понимаю что телепатов нет) - на C попробую только вечером.
    Вопрос (уточнение): при первом обращении всё в порядке, но длина обращения для чтения = <addr>,<cmd>,(size) указана только.
    при разбиении на два обращения для: <addr>,<cmd>,<mask_cmd>, (size) в этом виде не будет ли для каждого обращения посылаться адрес?
    собственно в байтах (побую на питон)

    требуется:
    послать запрос: 0x06(адрес) 0x06(команда) 0x04(маска команды)
    получить ответ: 0xXX 0xXX 0xXX 0xXX 0xXX 0xXX

    получается:
    послать запрос1: 0x06(адрес) 0x06(команда)
    послать запрос2: 0x06(адрес) 0x04(маска команды)
    получить ответ: - тишина (точнее какой-то непрерывный уровень)

    Может можно как-то по другому?
    Или реально только тупым киданием байтов с тактированием в i2c и таким же тупым тактированием и прослушиванием это реализовать возможно? - тоесть дёрганье ногами реализуя эмуляцию i2c в обход аппаратно-программной, которая имеется в Raspberry, а применять GPIO?
     
  6. Jeid

    Jeid Нерд

  7. Igor68

    Igor68 Гуру

    Спасибо большое, но я именно с этого и начинал ранее.
    в ComMotion driver for 4 motors сделали команду чтения состояния с кодом 6, после которой требуется послать байт с одним (из 8) активным (выставленным в 1) битом - которыйо пределяет:
    историю перегрузки проиводов;
    напряжение питания;
    текущее портебление каждого привода;
    и т.д.
    котрые шилд передаёт обратно.
    и похоже это они сделали под себя, сильно уйдя от принятого для стандартных устройств протокола.
    Все отальные команды - настройка, конфигурация, управление и т.д. проходят нормально.
     
  8. Igor68

    Igor68 Гуру

    Устал уже - забью на это большой и толстый и добавлю обработку команд в прошивку (получиться и команда и маска в одном байте):
    0x60 - для бита 0
    0x61 - для бита 1
    0x62 - для бита 2
    0x63 - для бита 3
    0x64 - для бита 4
    0x65 - для бита 5
    0x66 - для бита 6
    0x67 - для бита 7
    штатные оставлю на всякий случай - через час-другой будет готово.
    Если кому интересно - пишите в сообщение.
     
  9. Igor68

    Igor68 Гуру

    Простите - похоже я слишком "пальцы выставил" - после ряда проб вдруг обратил внимание на это:
    Код (C++):
    byte returnaddress=master;                                               // return address is I²C master by default
        if((request&127) && mcu==0) returnaddress=address+1;                     // bit 7 indicates internal request - return to other processor
        if((request&127) && mcu==1) returnaddress=address-1;                     // bit 7 indicates internal request - return to other processor
     
        Wire.beginTransmission(returnaddress);
        Wire.write(sendpack,spsize);
        Wire.endTransmission();
        command=255;
    а это означает что он ответит (точнее передаст сам как ведущее устройство), но только по адресу returnaddress, который выставляется в базовой конфигурации. Так,что фокус не удался (а какой адрес у Raspberry pi - он мастер), а в этой схеме два Atmega 328P, каждый из которых на этой плате имеет свой адрес согласно переключателям на плате (у меня 0x06(IC1), 0x07(IC2)) каждый для своей пары приводов - управление от Raspberry по IC1. Похоже так как я хотел пока не выйдет, т.к. контроллеры организуют псевдосеть, каждый из которых является ведущим и рассчитан на передачу параметров другому, прием от другого, но не выдавать параметры по запросу (я не знал и думал это i2c).
    Простите! Вопрос временно снят!
     
    Последнее редактирование: 30 июн 2016