Ви не увійшли.
Хоча б раз сюди зайти і все. NeedResetCounterOil ніде більше не змінюється
EEPROM.put(10, ImpulseOilMotor);
EEPROMClass::put() ідемпотентна: EEPROM.h:66. Комірка записується тільки якщо нове значення не дорівнює прочитаному. Просто буде постійно читати. Але це теж баг, вважаю.
Може це не від core залежить, а від даних в EEPROM? Спробуйте помістити в кінець setup:
ImpulseOilMotor = maxImpulseOilMotor+1;
І то правда. Шʼєм програматором - в еепромці або FF'ки, або старий контент, в залежності від фʼюзів та опцій програматора. З першим імпульсом FF'ки стають нулями. Шʼєм бутлоадером - micronucleus еепромку не чіпає, а якийсь інший може й стирає. В різних емуляторах також стан еепромки може зберігатись, а може й ні.
Я би очікував більш регулярного паттерну глітчів при суто логічних помилках в коді. Але ж код там такий, що пробуєш його читати - одразу виникає бажання переписати все нафіг. І тоді не вчитуєшся, наївно сподіваючись, що автор знав, що писав
А ШІМ на outMotorOil завдяки ось цим незалежним одна від одної умовам
Є таке. Тільки чому така залежність від версії core, різниця в реалізації millis() не мала би так впливати. Хоча тут спостерігається залежність і від частоти вхідних імпульсів.
Начебто всі записи в eeprom пов"язані з натисканням кнопки. Судячи по назвах змінних
Наче ж при кожному імпульсі подачі виконується EEPROM.put(10, ++ImpulseOilMotor).
Щось цей simutron якийсь дивний.
Та виглядає як творчість шкільного гуртка Ледве допер, що якщо файл прошивки оновився, весь застосунок потрібно перезапускати і відкривати проект заново. Бо він завантажує файл прошивки не кожний раз при старті симуляції, а тільки один раз. І автоматичний запуск симуляції при старті бісить. Таке, можна викидать
Ще один недолік у програмі: постійний перезапис однієї і тієї ж комірки в EEPROM. Даташит обіцяє 100'000 циклів перезапису. При записі раз на 3 секунди менше ніж за 100 мотогодин ресурс вичерпається.
Обідно що глюк з логічними рівнями зламався сам по собі
У мене склалося враження, що відтворюваність залежить від того, чи почистили кеш фреймворку після зміни борди в IDE або встановлення іншого BSP. В лінухах він в ~/.cache/arduino/. У IDE ще є свій RAM-кеш в /tmp/arduino-ide2-<sketch_id>/, який зберігається при перезапуску IDE. Але він щось пустий.
Намагався повторити ситуацію - наче IDE при зміні борди перезбирає ядро заново, тільки вже при повторних білдах бере з кеша:
Compiling core...
Using previously compiled file: .../.cache/arduino/sketches/88E89C526180E920CC9AC97AD811FBB4/core/pins_arduino.c.o
Using precompiled core: .../.cache/arduino/cores/digistump_avr_digispark-tiny_3c94b2ea733e4d576f0033e398c581c3/core.a
а надійніше переписати як state machine.
Потрібно його або переписувати з 0
Якщо мета - отримати працюючу програму, то написати з нуля - це найпростіший варіант
Особисто мені, наприклад, було би цікавіше докопатись до причини: в якому саме рядку digitalWrite() скидає стан піна в 0 через неправильно побудовану умову. А для цього потрібно досягти детермінованої відтворюваності в емуляторі при перезбірці прошивки.
В протеусі аналогічно
Це на PB1 чи на PB2?
Присвюювання змінним типу boolean HIGH або LOW теж якось око ріже.
Теж звернув увагу, дивний "стиль". Хоча з точки зору мови все валідно.
та й (millis() > (durationLongPressMode + btnModeNoLongPressed)) and (LongPressMode == HIGH)
не зовсім з тієї опери
Чому ж, в C++ and, or, not - така ж валідна форма булевих операторів, як і &&, ||, !. Сам іноді використовую таку форму.
Ну так і так millis переповниться через 50 днів.
millis не "переповнюється", для unsigned типів застосовується модулярна арифметика.
Чи для unsigned переповнення при відніманні не undefined behavior?
Для unsigned і при додаванні ніякого undefined behavior нема.
Просто порівнювати потрібно інтервали, а не точки часу.
А якщо вирізати частину, яка рахує кількість спрацювань насосу, це зробить стабільним пристрій?
Так як точної причини глюку ми не знаєм, то перевірити це може тільки той, у кого є пристрій.
Які є кращі ідеї? Є якийсь софтовий таймер, чи підпирати перевірками?
if (millis() - btnModeNoVeryLongPressed > durationVeryLongPressMode)
Доречі, в програмі є й інші баги, не повʼязані з сигналом на піні. Наприклад, конструкції типу
if (millis() > (durationVeryLongPressMode + btnModeNoVeryLongPressed))
на граничних значеннях (на 50-й день роботи ) працюватимуть неправильно.
@JokeR, вам же наче вдавалось відтворити баг? А можете зашарити .lst-файл прошивки, на якій баг стабільно відтворюється? IDE наче створює .lst при експорті бінарика і кладе його поряд.
Тому що в EEPROM.h нічого цікавого немає.
Тепер я зрозумів, чому IDE не показало команди компіляції. Бо ця EEPROM - header only.
Це враппер до avr/eeprom.h, а реалізація роботи з eeprom - упсь, в бінарнику.
Реалізація в avr-libc: libc/misc/eewr_byte.S
Вона в ісходніку виглядає страшно, бо там реалізація для всіх платформ. А в згенерованому коді для attiny85 досить проста:
0000096c <eeprom_write_byte>:
96c: 26 2f mov r18, r22
0000096e <eeprom_write_r18>:
96e: e1 99 sbic 0x1c, 1 ; 28
970: fe cf rjmp .-4 ; 0x96e <eeprom_write_r18>
972: 1c ba out 0x1c, r1 ; 28
974: 9f bb out 0x1f, r25 ; 31
976: 8e bb out 0x1e, r24 ; 30
978: 2d bb out 0x1d, r18 ; 29
97a: 0f b6 in r0, 0x3f ; 63
97c: f8 94 cli
97e: e2 9a sbi 0x1c, 2 ; 28
980: e1 9a sbi 0x1c, 1 ; 28
982: 0f be out 0x3f, r0 ; 63
984: 01 96 adiw r24, 0x01 ; 1
986: 08 95 ret
При використанні функцій з eeprom.h все так само ламається.
А, не знав, що з libc'шними функціями той глюк теж проявляється.
Тоді може це просто сайд-ефект через таймінги, і відповідний delay() замість eeprom_write_byte() так само впливатиме.
А збірка в platformio працює тільки тому що інша версія avr-gcc
https://raw.githubusercontent.com/ArminJo/DigistumpArduino/master/package_digistump_index.json же ж. Без ніяких хитрощів.
А, в 1.7.5 EEPROM уже є в поставці. Тільки IDE навіть з verbose mode не показує як її компілює, тільки Compiling library "EEPROM".
Але автор писав, що доставляв ще якусь додатково. От якщо ліби з однаковими іменами є і в packages/digistump/hardware/avr/1.7.5/libraries/, і в ~/Arduino/libraries, яку з них воно бере? Це тільки з лога збірки можна побачити:
Alternatives for EEPROM.h: [EEPROM@2.0]
ResolveLibrary(EEPROM.h)
-> candidates: [EEPROM@2.0]
...
Using library EEPROM at version 2.0 in folder: ...
І який там Clock обрано в меню, теж може впливати.
Є підозра що емулятор цього не покаже. Якщо косячаться логічні рівні на виході - значить там всередині щось комутується неправильно.
Якщо апаратний баг, то так. Але в datasheet errata нічого такого нема. Тільки для ревізії A "EEPROM read may fail at low supply voltage / low clock frequency".
А у випадку програмного багу як мінімум стан регістрів можна перевірити. Взагалі можна було б і просто асемблерний код проаналізувати, але мені за то не заплатять
До речі, в якійсь з ревізій цих tiny85 щось було з eeprom, саме з записом в 0 адресу, і були рекомендації від аксакалів починати запис з 10..
Наскільки знаю, то якщо бутлоадер теж використовує EEPROM для збереження своїх даних. Micronucleus такого не робить наче.
А так, відчуття якоїсь незавершеності.
У мене це відчуття щодо більшості інструментів для розробки під МК
Якраз нещодавно хотів в simavr перевірити ту багу з attiny85. Але ж ні URL та версії тієї EEPROM бібліотеки, ні опцій збірки так і не отримав, щоб відтворити збірку 1-в-1.
У когось вийшло?
Колись трошки грався з самим simavr (не в рамках platformio). Ну, воно працює, вивод на UART показує в консолі, gdb чіпляється як до будь-якої іншої remote target. Але для моніторингу периферії потрібно додавати код в саму фірмварь.
Якщо у Вас все це проінстальвано, й налаштовано, чи можна Вас попросити, скомпілювати прошивку, для проби?
Та льогко: DigiSpark_Oiler_Moto_hex.zip
Тобто, я встановлюю цей софт, копіюю текст скетчу, вставляю скопійоване, додаю Arduino.h на початку, отримую hex, пишу його в плату, через програматор.
Так?
Як під віндою його ставити і користуватись не знаю, вибачте. Під лінухами я просто встановив пакет platformio-core з репозиторію.
Створюю директорію і проект в ній:
$ mkdir test-project
$ cd test-project
$ pio project init -b digispark-tiny
Копіюю ваш скетч в test-project/src/, дописую на початку "#include <Arduino.h>", збираю:
$ pio run
(а краще "pio run -v", щоб бачити, які команди воно викликає).
Для прошивки зазвичай достатньо
$ pio run -t upload
Для digispark-tiny, мабуть, повинно так само працювати. Принаймні у мене воно скачало й запустило micronucleus, просить підключити плату.
Всі налаштування в platformio.ini.
Бінарик, hex та інші артефакти лежать в .pio/build/digispark-tiny/
Якщо так, то чи підійде цей код, чт треба все переписувати заново?
Може що порадите?
PlatformIO
Скетч збирається без переписування, тільки в самому початку додати
#include <Arduino.h>
Стосовно еепрому.
Може його прочитати програматором, і глянути, де нічого не пишеться, і саме туди писати дані.
Чим писати, бібліотекою EEPROM, яка в EEPROM нічого не пише, а пише в регістри або RAM?
Спершу впевніться, що проблема викликана записом в EEPROM. Мої здогадки тільки теоретичні, бо не знаю, яку саме бібліотеку і як ви там встановлювали, і не маю заліза, щоб перевірити.
Також спробуйте зібрати скетч за допомогою platform.io, з його дефолтним framework-arduino-avr-digistump.
Що за бібліотеки мені треба завантажити, щоб все працювало нормально?
Я би спершу зʼясував, чи це проблема з самою лібою EEPROM, чи з функціями eeprom_write_* з avr/eeprom.h. Якщо функції eeprom_write_*/eeprom_read_* працюють нормально, то використав би їх, без всяких бібліотечних обгорток.
А якщо вирішувати глобально, то не користувався би Arduino IDE.
Можете глянути, наче Compare Match Output вимкнуто.
Цей витвір ШІ працює нормально? А якщо в setup() закоментувати запис в TCCR0A?
Може там вказати адресу еепром 100, або 200 ?
Якщо EEPROM працює неправильно, то вона працюватиме неправильно і з іншими адресами. Буде псувати якусь іншу область памʼяті.
Скомпілюйте скетч з нуля, з увімкненим verbose compiler output. Покажіть лог збірки.
Дивіться, яка цікава річ. У вас EEPROM.put(10, ImpulseOilMotor) має записувати два байта в EEPROM за адресою 10.
Якщо припустити, що ваша ліба EEPROM зібрана якось неправильно (з іншим -mcu, наприклад), і замість EEPROM пише в адресний простір даних, то адреса 10 попадає на адресу 0x2A в I/O просторі. Це якраз регістри TCCR0A та OCR1B, які відповідають за Compare Match Output для PWM.