• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Делюсь опытом AdHoc пошаговое руководство

pvvx

Активный участник сообщества
куда как интереснее послушать как в Power Profiler сделано сейчас.
Код:
typedef struct {
    uint8_t dev_addr; // адрес на шине i2c
    uint8_t reg_addr; // номер регистра чтения
} reg_rd_t;

typedef struct {
    uint8_t dev_addr; // адрес на шине i2c
    uint8_t reg_addr; // номер регистра чтения
    uint16_t data; // значение для записи в регистр
} reg_wr_t;

#define MAX_INIT_REGS 4
#define MAX_READ_REGS 4

// Структура конфигурации опроса и инициализации устройства
// Выходной пакет непрерывного опроса формируется по данному описанию
typedef struct {
    uint8_t rd_count; // кол-во регистров для разового чтения
    uint8_t init_count; // кол-во регистров для инициализации
    uint16_t time; // частота опроса разового чтения
    uint16_t clk_khz; // частота i2c шины
    reg_wr_t init[MAX_INIT_REGS];
    reg_rd_t rd[MAX_READ_REGS];
} dev_cfg_t;

// Выходной пакет примерно такой
typedef struct {
    uint8_t id; // тип пакета   
    uint8_t cnt; // последовательный номер пакета
    uint16_t reg[кол-во]; // сборка регистров указанная в кол-ве регистров для разового чтения и описание какие в reg_rd_t,
    // набор до 30 шт при USB-UART USB1.1 (до 64 байта пакет),
    // кол-во зависит от скорости опроса ADC.
} out_pkt_t;
 

cheblin

Member
C:
typedef struct {
    blk_head_t head;
    union {
        uint8_t  uc[VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)];
        int8_t   sc[VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)];
        uint16_t ui[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(uint16_t)];
        int16_t  si[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(int16_t)];
        uint32_t ud[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(uint32_t)];
        int32_t  sd[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(uint32_t)];
        reg_wr_t reg;
    }          data;
} blk_cio_t;
и вот это... спасибо.
 

pvvx

Активный участник сообщества
Более конкретно - не задействованная возможность на верхнем уровне ПО по дерганию ножками данного MCU.
В другом ПО это выглядит так:
upload_2020-1-10_20-34-55.png
И каждый кружок вызывает конфигурацию вывода:
upload_2020-1-10_20-35-36.png
Более детально что это всё значит смотреть в PDF на использованный MCU.
 

pvvx

Активный участник сообщества
C:
typedef struct {
    blk_head_t head;
    union {
        uint8_t  uc[VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)];
        int8_t   sc[VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)];
        uint16_t ui[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(uint16_t)];
        int16_t  si[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(int16_t)];
        uint32_t ud[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(uint32_t)];
        int32_t  sd[(VIRTUAL_COM_PORT_DATA_SIZE - sizeof(blk_head_t)) / sizeof(uint32_t)];
        reg_wr_t reg;
    }          data;
} blk_cio_t;
и вот это... спасибо.
Это как выглядят разные типы данных в памяти у данного MCU и сколько их может вмещаться в пакет с ограничением в VIRTUAL_COM_PORT_DATA_SIZE, а так-же как обратиться CPU к энному элементу при одинаковом их типе в наборе :p
 

pvvx

Активный участник сообщества
Что ещё вас там интересует?

Что нужно выкинуть, т.е. сколько там ненужного и не оптимизированного кода?

Например заголовок там не удален с того века, когда писался какой-то паскалевский драйвер – он же и прикручен в основной программе. Актуальность у нем была когда вышел Borland Delphi7. С тех времен не менялся и на его основе за полчаса была сформирована первая версия PowerProfiler-а…
Что-то ещё там такое-же сидит... Но мне лень разгребать тысячный вариант своей лепнины... :)
 

pvvx

Активный участник сообщества
Вспомнил! Там по началу был дугой код USB-COM от ST, другая либа, какая-то из первых, глючная.
Потом система драйвера у ST сменилась, вместе с алгоритмами и вызовами. Но мне было лень всё переписывать. Поменял дрова, а алгоритм как-то скривил, чтобы он пахал и на новом драйвере :rolleyes:
 

cheblin

Member
понятно. тут играем, тут не играем, а тут рыбу заворачивали...

похоже переделывать придётся всё. поначалу была иллюзия встроится и клиента не ломать. но там ценнного нуль.

итак:
считываются показания uint16_t с датчиков на smbus по таймеру... так?
период отсчётов 100 us?
сколько делать отчётов в одной отправке?
подстраиваться под VIRTUAL_COM_PORT_DATA_SIZE ?

короче нужен требуемый алгоритм обмена. интересует именно главный функционал - сбора и отправки данных.
управление устройством, подстройки, и конфигурирование это всё второстепенное и делается элементарно.

Код:
// Выходной пакет примерно такой
typedef struct {
    uint8_t id; // тип пакета
    uint8_t cnt; // последовательный номер пакета
    uint16_t reg[кол-во]; // сборка регистров указанная в кол-ве регистров для разового чтения и описание какие в reg_rd_t,
    // набор до 30 шт при USB-UART USB1.1 (до 64 байта пакет),
    // кол-во зависит от скорости опроса ADC.
} out_pkt_t;
uint8_t cnt; // последовательный номер пакета
нафига?
разве USB транспорт не гарантирует очерёдность пакетов?

uint16_t reg[кол-во]; // сборка регистров указанная в кол-ве регистров для разового чтения и описание какие в reg_rd_t,
для чего это передавать?
разве устройство и клиент при коннекте не согласовывают эти настройки?




есть какие либо идеи про клиента? есть предпочтения?
 

cheblin

Member
Код:
// Выходной пакет примерно такой
typedef struct {
    uint8_t id; // тип пакета
    uint8_t cnt; // последовательный номер пакета
    uint16_t reg[кол-во]; // сборка регистров указанная в кол-ве регистров для разового чтения и описание какие в reg_rd_t,
    // набор до 30 шт при USB-UART USB1.1 (до 64 байта пакет),
    // кол-во зависит от скорости опроса ADC.
} out_pkt_t;
в исходниках out_pkt_t нет
аналог?
 

pvvx

Активный участник сообщества
в исходниках out_pkt_t нет
аналог?
Вам упрощенный пример тут в теме описал. В нем и есть out_pkt_t.
понятно. тут играем, тут не играем, а тут рыбу заворачивали...
похоже переделывать придётся всё. поначалу была иллюзия встроится и клиента не ломать. но там ценнного нуль.
А исходники PowerProfiler уже утречком пробежался, т.е. сменились - выкинуто лишнее (старые заголовки у пакета) :p
сколько делать отчётов в одной отправке?
подстраиваться под VIRTUAL_COM_PORT_DATA_SIZE ?
Задаваемая длина пакета при соединение (перед стартом передачи данных).
uint8_t cnt; // последовательный номер пакета
нафига?
разве USB транспорт не гарантирует очерёдность пакетов?
А пропуск по чьей-либо вине, включая hub?
Будем вводить сообщения об ошибках с обоих сторон?
Кароче можно без этого резервного байта...
uint16_t reg[кол-во]; // сборка регистров указанная в кол-ве регистров для разового чтения и описание какие в reg_rd_t,
для чего это передавать?
разве устройство и клиент при коннекте не согласовывают эти настройки?
Вот это и есть массив переменным размером "кол-во" в котором и лежат значения регистров с ранее оговоренной последовательностью.
 

pvvx

Активный участник сообщества
Какие у вас сложности с передачей 16 бит от устройства на i2c с задаваемым интервалом c помощью самого дешевого STM32 в USB-COM и прием в компе?
Задача на десять-пятнадцать минут с полным описанием с нуля всех исходников.

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

cheblin

Member
Задача на десять-пятнадцать минут
на данном подсайте гений только один - ВЫ
правда вот глядя на исходники не нахожу этому подтверждения...но ВЫне огорчайтесь ...

..а нам тупить и заниматься своими делами позволительно, да...
мы в гении не лезем.
 

pvvx

Активный участник сообщества
на данном подсайте гений только один - ВЫ
правда вот глядя на исходники не нахожу этому подтверждения...но ВЫне огорчайтесь ...

..а нам тупить и заниматься своими делами позволительно, да...
мы в гении не лезем.
У вас что комп так тормозит в STM32CubeMX? Там, в зависимости от чипа, надо вписать - в подготовленной для вас средой процедуре таймера чтение регистра i2c и значение положить в буфер. При накоплении n значений вызвать передачу буфера в USB.
Это долго?
 

cheblin

Member
upload_2020-1-11_17-26-42.png

как жеж мне "дорог" этот С... с этими постоянными клэшами имён. тьху гадость...
 

pvvx

Активный участник сообщества
Посмотреть вложение 8571

как жеж мне "дорог" этот С... с этими постоянными клэшами имён. тьху гадость...
Я вот тут подумал и осознал, свою ошибку! Каюсь. Совсем забыл, что вы с MCU никогда не работали и для вас это неопознанный мир...
Нашел SoC, который я ещё не изучал и засек время.
Ушло 22 минуты на всё - с поиском платки, проводков и прочими подготовками, да ещё общением с детками и женой....
Но больше всего после этого ушло на фото и прочую подготовку картинок для вас
"Как считать регистр значения тока из IN226 и передать в USB".
Взял nRF528240.
Открыл пару примеров и сделал копипаст мышкой. Добавил пару переменных, потоптав клаву:
Код:
/*********************************************************************
  This is an example for our nRF52 based Bluefruit LE modules
  Pick one up today in the adafruit shop!
*********************************************************************/
#include <Arduino.h>
#include <Wire.h>
SoftwareTimer blinkTimer;
void setup()
{
  Serial.begin(115200);
  while ( !Serial ) delay(10);   // for nrf52840 with native usb-com
  // Configure the timer with 1000 ms interval, with our callback
  blinkTimer.begin(50, blink_timer_callback);
}
size_t adc_buffer_wr_idx = 2;
// sends regs 0x00 config data:
// 0x0125 : 1.1 ms Shunt Only
// 0x0127 : 1.1 ms Shunt & Bus
uint8_t ina226_config[3] = {0x00, 0x01, 0x25};
uint8_t inited = 0;
uint8_t adc_buffer[62];
void loop()
{
  if (!inited) {
    adc_buffer[0] = 0x55; // header code
    adc_buffer[1] = 0x07; // block id
    Wire.begin();        // join i2c bus (address optional for master)
    Wire.setClock(TWIM_FREQUENCY_FREQUENCY_K400);
    // device address is specified in datasheet
    Wire.beginTransmission(0x40); // transmit to device 0x40
    Wire.write(ina226_config, 3); // set regs config
    Wire.endTransmission();     // stop transmitting
    inited = 1;
    // Start the timer
    blinkTimer.start();
  }
}
void blink_timer_callback(TimerHandle_t xTimerID)
{
  (void) xTimerID;   // freeRTOS timer ID, ignored if not used
  digitalToggle(LED_RED);
  // request 2 bytes from slave device 0x40 register 0x01
  if (inited) {
    Wire.beginTransmission(0x40); // transmit to device 0x40
    Wire.write(0x01);
    Wire.endTransmission();     // stop transmitting
    Wire.requestFrom(0x40, 2);
    if (2 <= Wire.available()) {   // if two bytes were received
      adc_buffer[adc_buffer_wr_idx++] = Wire.read();  // receive high byte (overwrites previous reading)
      adc_buffer[adc_buffer_wr_idx++] = Wire.read(); // receive low byte as lower 8 bits
      if (adc_buffer_wr_idx >= sizeof(adc_buffer)) {
        adc_buffer_wr_idx = 2;
        Serial.write((const uint8_t *)adc_buffer, sizeof(adc_buffer));
      }
    }
  }
}
Запустил:
upload_2020-1-11_15-17-41.png
Глянул ослом ноги i2c - дрыгают, но протокол обрывает - нет самого датчика на i2c.
Далее воткнул на соплях плату c INA226 в модуль MDK_USB_Dongle:
upload_2020-1-11_15-21-54.png
Паять грешно! :)

Проверил, что шина стала читаться и с ACK всё в порядке:
upload_2020-1-11_15-23-40.png
Включил китай-монитор COM-порта и наблюдаю нужные пакетики:
upload_2020-1-11_15-22-56.png
Вроде всё.
Далее хоть на питоне...
 

cheblin

Member
да, я не ардуинщик..
так оригинально отключать куски кода не умею... . всё так.
 

cheblin

Member
Офигиваю с дури компилятора кайла. На этот код
upload_2020-1-12_11-24-56.png

выдаёт ошибку.

upload_2020-1-12_11-27-11.png

требуя писать так
upload_2020-1-12_11-23-23.png

в то время как ВСЕ прочие С компиляторы прекрасно воспринимают этот код.

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

Тошниловка...
 
Сверху Снизу