Ви не увійшли.
Верхній кінець R23 до джерела імпульсів підключений?
Так
У джерела пушпульний вихід чи відкритий колектор з підтяжкою?
Чорний ящик
Плата розміром з ноутбук, щедро заляпана компаундом. В оригінальному пульті взагалі цікаво (респект німцям що відреверсили)
https://akkudoktor.net/uploads/short-url/t52nbsj6dSc9dz2ltItHY7x1w6V.pdf
Чи так вони навернули зверху софтово-залізний трігер Шмідта, чи ця штука універсальна і уміє підключатись до single wire uart..
Але там attiny, 5В, вбудовані тригери Шмідта (в esp32c3 їх немає)..
цей обробник в контексті переривання виконується чи в контексті задачі?
Переривання. Ну, хз. Пишуть, що некошерно, бо блокує основний потік, але на пару мкс нормально.
Можна програмний debouncing реалізувати
Він сам по собі вийшов
Далі по коду малі інтервали ігноряться, а закладеної похибки в +-5мс вистачає щоб вивезти ![]()
Відпаяв конденсатор - в принципі так теж працює. Фронти на вході кривенькі, так.
Але що ще більш дивує - 
Те що на зворотньому фронті теж можливі артефакти - припустимо. Але як переривання може спрацювати сильно до спаду імпульса? 45 мкс - дофіга.
як прикріпити фотку?
Через Завантаження ![]()
Welcome to 2000 ![]()
Колупаю протокол виносного пульта до інвертора Ective. Нічого складного, звичайна PWM. І все наче працює.. Дані успішно розкодовуються (там 1 байт всього
) Але щось мене смущає.
Вхідний ланцюжок зробив так. імпульси 5В (але хто знає наскільки з цим строго), довжина 18мс, період від 50 до 100 мс. На кожний наростаючий фронт налаштував переривання. Всередині таке:
// Обробник переривання GPIO (викликається при кожному наростаючому фронті)
static void IRAM_ATTR ective_isr_handler(void *arg)
{
uint64_t count_value;
if (gpio_get_level(GPIO_INPUT_ECTIVE) == 0)
{
// Якщо сигнал низький, ігноруємо його.
return;
};
// Отримуємо поточне значення таймера в мікросекундах
gptimer_get_raw_count(gptimer, &count_value);
// Скидаємо таймер в 0 для вимірювання наступного періоду
gptimer_set_raw_count(gptimer, 0);
gpio_set_level(2, 1); // Встановлюємо GPIO 2 в LOW для відладки
esp_rom_delay_us(10);
gpio_set_level(2, 0); // Встановлюємо GPIO 2 в LOW для відладкиТобто очікується на нозі GPIO2 1 імпульс довжиною 10 мкс. А в реальності іноді 1 імпульс, іноді 3:
Що дуже дивно. Підозрюю що сигнал на вході брудний, але подивитись нічим. SCO2 як виявилось не осцилограф а скоріше імітація. Синхронізується на нерегулярних сигналах не дуже, waveformи зберігати не вміє.
Питання: які є осцилографи, що вміли зберігати waveform, щоб не по ціні Боїнга? ![]()
В принципі можна спробувати замість обмежувача на стабілітроні трігер Шмідта впаяти..
Тільки там з HCPL-2300
480 UAH
По богатому ![]()
PC817 - 5 UAH
Час вмик/вимк Ton/Toff, µs: 18/18 µs. Повинно вистачити для 9600. Але няп треба зарядити струм не 5мА, а 20.
Взагалі їх як грязі трохи є в наявності в магазинах, і швидших, і недорогих.
Коли вдома є автономна енергосистема (акумулятори, інвертори, UPS чи сонячні панелі), швидко приходить усвідомлення: все це хазяйство потребує моніторингу. Завжди корисно знати, скільки залишилося заряду, яка напруга та чи не ввімкнув хтось аерогриль.
Стандартом де-факто для автоматизації є Home Assistant (HA). Проте розгортати його на окремому ПК чи купувати одноплатний мікрокомп"ютер якось занадто. Бюджетна альтернатива — звичайний Android TV Box, який можна перешити на сервер з linux.
Нижче — трохи реального досвіду, підводні камені та лайфхаки. Не покроковий рецепт, ніяких схем чи конфігів - впевнений що у кожного своє видіння прекрасного, а лиш напрямок куди можна рухатись.
Для збору метрик і малювання графіків потужності TV Box вистачає з головою. Основна вимога — підтримка Linux. Але якщо ви вирішите піти цим шляхом - буде трохи цікавого:
- 32/64 біт. Більшість ультрабюджетних медіаплеєрів мають 32-бітну архітектуру. Оскільки офіційна підтримка 32-розрядних ОС у Home Assistant давно припинена, доведеться шукати застарілі версії HA (я взяв armv7-homeassistant:2025.11.3). Вони працюють, але виставляти таку систему назовні в інтернет — категорично не варто. Та і взагалі, домашній датацентр, з свічами, vlan'ами і віртуальними серверами - це для реальних гіків, а наш девіз - кожен бомж має право на свій маленький Home Assistant. Мені дістався IPnet TV Box (CPU: RK3229, 1.5GHz, Quad Core , RAM: 1G).
- Специфічні ядра Linux. Популярний дистрибутив Armbian може не підтримувати залізо TV Box. Hardware зазвичай заточене під рідне вендорське ядро (чи ядро під hardware). Оновите ядро до актуального — відваляться eMMC, Wi-Fi або Bluetooth. Залишитеся на старому ядрі (наприклад, 4.4) — не запуститься Docker, який потрібен для сучасного HA. Запускати той археологічний HA, який був ще до docker - не для слабаків, хоча в принципі теж реально.
- Убита пам'ять. Якщо TV Box купувався на вторинному ринку за недорого під ремонт- вбудована пам'ять eMMC скоріш за все уже мертва або близька до цього. Можна погратись з badblocks, знайти биті сектори, переформатувати розділи.. Але чи на довго його вистачить?
Робочий сетап: беремо стабільний Armbian (я взяв v26.11), накочуємо його на хорошу, нову SD-карту (16 Гб - політ нормальний), а мережу підключаємо виключно через Ethernet-кабель, щоб не гратися з драйверами Wi-Fi.
Важливий момент: треба мінімізувати використання флешки на запис. Тому всі логи пишуться в tmpfs, інтервал синхронізації ФС збільшуємо до 10хв.
Спосіб підключення сенсорів струму та напруги залежить виключно від «вихованості» вашого заліза:
1. Нативно: Ваш UPS підтримується Home Assistant з коробки. Конектимо напряму і радіємо життю.
2. Через MQTT: UPS вміє віддавати дані за протоколом MQTT. Піднімаємо на TV Box брокер (наприклад, Mosquitto), куди сенсори зливають інфу, а HA підтягує її для візуалізації.
3. Хмара вендора (Тяжкий випадок): Якщо залізо спілкується тільки з сервером виробника, шукайте готові кастомні інтеграції. Якщо їх немає - упсь. Див. п. 5.
4. Тільки мобільний додаток: Тут цікаво. Наприклад, у моєму кейсі (RED ODO 12.8V 140Ah LiFePO4 Battery) вдалось знайти код підтримки BMS із забутої девелоперської гілки HA та власноруч портувати його на ESP32, щоб подружити залізо з моніторингом.
5. Саморобка. Додати пару своїх датчиків точно зможете. Гугліть home assistant mqtt discovery.
Оскільки Home Assistant крутиться на старому софті без оновлень безпеки, відкривати для нього порти на роутері категорично не варто. Але моніторити систему з телефона, перебуваючи поза домом, корисно.
Рішення - міст через зовнішній MQTT-брокер:
Замість того, щоб відкривати доступ до адмінки HA, можна налаштувати локальний MQTT-брокер на автоматичний експорт потрібних топіків у зовнішній хмарний брокер.
Як це працює: Дані з датчиків дзеркалюються у хмару. Мобільний додаток на телефоні підключається до цієї хмари й показує вам графіки. Єдина незручність - графіки малюються поки MQTT клієнт запущений, історію видно тільки в HA.
Чому це круто: Це абсолютно безпечно (зовнішнього доступу до вашої локальної мережі та адмінпанелей немає взагалі). До того ж, більшість хмарних MQTT-брокерів мають Free Tier (безкоштовний ліміт), якого для домашнього моніторингу вистачає з головою.
Нічого не зрозуміло але дуже цікаво (ц)
Що це взагалі було? Якийсь потік сознанія. Це ви зробили, чи хочете зробити, чи десь купили, чи хочете продати..?
Взагалі крутити котлом через opentherm цікаво, але особливого смислу я не бачу. Ну, то таке. Існують сценарії де воно непогано. Заміський маєток, куди ви навідуєтесь раз на тиждень ![]()
Незрозуміло, навіщо чіпати насос - котел і сам непогано ним управляє.
Температура 29С - для сауни малувато, для житла забагато.
І, того, не одному екрані написи і на російській і на український.. WTF?
Я щось таке і підозрював. Тому мені і не дуже подобається Arduino over esp-idf. Крок в сторону від blink - і то пам"ять тече, то щось внєзапно падає.
хттпс://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/performance/size.html
Насправді там є що вимкнути
IPV6, VFS.. Допомогло.
Трохи цікавих дослідів ![]()
Зробив саморобку на esp32-c3 + Arduino + FreeRtos. Нічого неймовірного: саморобний драйвер двигуна з аналоговим датчиком Холла, wifi, mqtt, mdns, веб-морда. Працює, але виглядає.. як Arduino - купа ліб, написаних різними людьми.. Вирішив зробити трохи рефакторінга - переписати на чесне esp-idf + freertos. Все що потрібно в esp-idf наче є. Та таска, що з wifi - без проблем; запустилась майже зразу. MDNS - теж. А з mqtt - перестало влазити в флешку. Якщо вимкнути debug - влазить.. але нам так незручно
Під Arduino все влізло без ніякого байто@@бства.
От і питання - може є спосіб збирати свій код з клочом -Og, а бібліотечний - з -Os ?
Ну gdb-multiarch має ж якось взнати, що є ttyACM0, на якому його будуть слухати.
Через файл gdbinit ![]()
Магічний пристрій і є монітор, який реалізує протокол gdb-сервера.
Походу його не навчили цьому ![]()
Ну reset то таке.. можна і руками.. а що debug не працює - незручно ![]()
А ви gdb з монітором зʼєднали?
Складно ![]()
У нас є gdb-multiarch, є ttyACM0, є магічний пристій, що слухає ttyACM0 і смикає CH32V003 за SDIO.
А "monitor reset" працює?
ніт, "monitor" command not supported by this target.
потрібно збирати з -Og,
$CC -g -O0 -ffunction-sections -static-libgcc -lgcc -march=rv32ec_zicsr -mabi=ilp32e -I/usr/include/newlib -nostdlib -I. -Wall -c ch32v003fun.c -o obj/ch32v003fun.oщось недороблене ![]()
gdb-multiarch -x gdbinit -ex 'load' -ex 'detach' -ex 'quit' bin/blink.elfТрохи дивує що заливається не .bin, а .elf. Десь під капотом повинна бути магія objcopy?
А якщо той же бінарик зашити заздалегідь робочим програматором?
Зашивається, працює
Через ardulink, зроблений з arduino, і пише і читає. Ок ![]()
Ага, трохи роз"ясняється. picorvd - заливає прошивку правильно, але в кінці не робить reset. ardulink, походу, робить reset через живлення
Якщо ребутнути через power - blink запускається. Але з debug - облом ![]()
GNU gdb (xPack GNU RISC-V Embedded GCC x86_64) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv-wch-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bin/blink.elf...
0x000001e4 in busywait (x=600000) at blink.cpp:4
4 for (volatile int i = 0; i < x; i++) {
(gdb) break 10
Breakpoint 1 at 0x212: file blink.cpp, line 10.
Note: automatically using hardware breakpoints for read-only addresses.
(gdb) break 11
Breakpoint 2 at 0x214: file blink.cpp, line 13.
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x000001e4 in busywait (x=<error reading variable: Cannot access memory at address 0xfffffff4>) at blink.cpp:4
4 for (volatile int i = 0; i < x; i++) {
(gdb) Щось там недороблено ![]()
хттпс://github.com/aappleby/picorvd
Надибав таке. Виглядає непогано, і rp2040 в хазяйстві є ![]()
Але не працює ![]()
blink наче заливає, але рівень на пінах не міняється.
При спробі debug - відтворюється хттпс://github.com/aappleby/picorvd/issues/8
Що хотів сказати автор issue.. Не та версія компілятора? gdb? А яка потрібна? ..
Жаль що до кінця ту штуку не доробили ![]()
потрібно було не з першого канала почінати, а з 5...
Або return в кожний if
Взагалі по можливості треба уникати копіпасти з вкладеними if ами. Потім складно зрозуміти що там взагалі відбувається. Особливо якщо ні з debug_ером ні з print не підлізти.
У 8 ногих дрібноконтролерів свій шарм
Так, теж прошивається.
board = genericCH32V003J4M6wch-linkE сам по собі на CH32V305 зроблений)
Інший контроллер, і ціна інша ![]()
Купив собі колись кілька плат з CH32V003F4P6 на розпродажі, і програматор, і нарешті дійшли ручки іх помацати ![]()
І вияснилось, що програматор не той
Я купив wch-link, а треба wch-linkE ![]()
Але не все так фатально. В інтернетах є проект емулятора minichlink на arduino ![]()
Береться хттпс://github.com/Community-PIO-CH32V/Ardulink-pio, зашивається звичайним способом в Arduino (я взяв Uno). Для інших варіантів треба вказати правильну плату, з правильною частотою резонатора.
Тепер arduino стає Ardulink Programmer. І platformio може з ним працювати (mounriver-studio, на жаль, ні).
Якщо в platformio.ini вписати
[env:ch32v003f4p6_evt_r0]
platform = ch32v
board = ch32v003f4p6_evt_r0
framework = arduino
upload_protocol = minichlink
upload_port = /dev/ttyACM0
upload_flags = "-c ${UPLOAD_PORT}"то все прошивається, правда повільно.
З"єднання таке:
Arduino - CH32
GND - GND
8 - 1K резистор - SWD
9 - V
Класичний blink
#include <Arduino.h>
#define LED_PIN PD0
void setup() {
pinMode(LED_PIN, OUTPUT); }
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(250);
digitalWrite(LED_PIN, LOW);
delay(250);
}працює, але не без особливостей. Internal LED тут припаяний до PD1, він же SWD, і, схоже, не можна його просто взяти і використати як GPIO.
Ну если всё записано в одну строчку, то в принципе нормально.
Для сіоністів може і нормально, (1 << CS10)| (.... ![]()
Краще вже як у лінуксоїдів
#define R_OK 4 /* Test for read permission. */
#define W_OK 2 /* Test for write permission. */
#define X_OK 1 /* Test for execute permission. */
#define F_OK 0 /* Test for existence. */надо писать именно так, как хочет конкретный компилятор, и пофиг что у другого по другому, они никогда не будут совместимы в этом плане.
Кросплатформна/кроскомпіляторна розробка добавляє складності. Таке життя. Я більше про те що часто копіпастять код виду
(0 << CS10)взагалі не задумуючись. Правильні макроси спрощують життя.
дофига не дофига, но я, например, окромя gcc пользовался еще codevision и iar. и как то кумарило, что попадались такие макросы, что свойственны конкретному компилятору.
![]()
в сторонніх лібах може бути що завгодно.
Можна подумати під avr дофіга компіляторів і TCCR1B з CS11 є на дофіга архітектурах ![]()
Ну вам залишилось Serv_4_1, Serv_4_2, Serv_5_1 .. занести в таблицю (масив)
І робити навігацію по масиву перемиканням індексу
І буде точно як в servo.cpp ![]()
TCCR1A = 0; // normal counting mode
TCCR1B = _BV(CS11); // set prescaler of 8
TCNT1 = 0; Зверніть увагу на макрос _BV, краще виглядає ніж (1 << CS11)
А ще краще як на мене
#define PRESCALER_8 (_BV(CS11))Нас рятує те що біти CS* після reset скинуті
.
Правильно мабуть
TCCR1B |= (1 << CS10);
TCCR1B &= ~(1 << CS11);
TCCR1B |= (1 << CS12);Або макросів навернути
Щоб якщо треба задати 3 біти - щоб вони не тільки встановлювались а і скидались. Ну або через змінну.
хттпс://godbolt.org/z/a5v8q5xzj
#include <avr/io.h>
int main() {
TCCR1B |= (0 << CS10) | (1 << CS11) | (0 << CS12);
}дає таку конструкцію
main:
push r28
push r29
in r28, 0x3d ; 61
in r29, 0x3e ; 62
ldi r24, 0x81 ; 129
ldi r25, 0x00 ; 0
movw r30, r24
ld r18, Z
ldi r24, 0x81 ; 129
ldi r25, 0x00 ; 0
ori r18, 0x02 ; 2
movw r30, r24
st Z, r18
ldi r24, 0x00 ; 0
ldi r25, 0x00 ; 0
pop r29
pop r28
ret#include <avr/io.h>
int main() {
TCCR1B |= (1 << CS11);
}відповідно, таку
main:
push r28
push r29
in r28, 0x3d ; 61
in r29, 0x3e ; 62
ldi r24, 0x81 ; 129
ldi r25, 0x00 ; 0
movw r30, r24
ld r18, Z
ldi r24, 0x81 ; 129
ldi r25, 0x00 ; 0
ori r18, 0x02 ; 2
movw r30, r24
st Z, r18
ldi r24, 0x00 ; 0
ldi r25, 0x00 ; 0
pop r29
pop r28
retрізниця відсутня ![]()
ну якби логічно, як 0 не рухай, він залишається 0.
Якщо розписати так
#include <avr/io.h>
int main() {
TCCR1B |= (0 << CS10); // Установить биты на коэффициент деления
TCCR1B |= (1 << CS11);
TCCR1B |= (0 << CS12);
}то таки чесно виконує безсмислену операцію
// TCCR1B |= (0 << CS12);
ld r24, Z
st Z, r24Ну я так розумію там відтворюється якийсь проект від Алекса Гувера. Краще тоді з мінімальними змінами. У нього, судячи з каментів в коді, теж на 8 мгц щось не так.