Написание скетча для arduino nano
- Войдите на сайт для отправки комментариев
Задача состоит в следующем, необходимо написать простой скетч для Arduino Nano v3 и ATtiny85
Понимаю, что для знающих людей данная задача не является сколь либо сложной, но сам пока не могу реализовать, ввиду не достаточного опыта программирования ардуин.
Исходные данные:
Имеется, датчик скорости и направления TLE4669 ;
Эл. двигатель с 10-ю магнитами на валу. Диаметр круга на которм по краю, размещены магниты 80мм;
Контроллер на Arduino Nano v3 и ATtiny85.
Задача: написать скетч для опледеления наличия (не скорости!) вращения и направления вращения вала.
Скорость вращения вала от 0 до 1000 об/м
При вращении вала в одном из направлений должено включаться одно из двух реле и загораться соответсвующий индакатор , указывающий на наличие вращения и направление этого вращения. Выключение реле и индикатора должны быть только после полной остановки вращения, допустимая задержка времени ожидания полной остановки до 1-1.5 секунд. Включение двух реле одновременно, не допустимо!
У датчиков TLE4669, направление вращения указывается изменением уровня сигнала на выходе, например, вправо логическая 1 влево 0, скорость на другом выходе, так же логическом. По ссылке выше можно узнать про датчик более подробно.
А чо, на лекции не ходил?
Когда я учился этого было только в фантастике и соответсвенно нам это не преподавали. Это для меня новое и вот сейчас изучаю самостоятельно.
В свое время собирал на логике, но не устраивает сейчас, хочется по компактнее ну и в ногу со временем.
Интересная штука. Я бы поковырял ея, если не к спеху.
Да, действительно интересная. Но времени у меня мало.
а задача уж больно смахивает на академическую.
а задача уж больно смахивает на академическую.
Мало - это сколько? Пишите подробности на wrk.sadman@gmial.com , если желаете.
P.S. Это не вы ли с MRTG у меня были?
Задача состоит в следующем, необходимо написать простой скетч для Arduino Nano v3 и ATtiny85
Понимаю, что для знающих людей данная задача не является сколь либо сложной, но сам пока не могу реализовать, ввиду не достаточного опыта программирования ардуин.
А как вы это понимаете, если сами не имете "достаточного опыта" ?
Почему два контроллера ?
Если готовы заплатить больше 10000 рублей и находитесь в Москве то brokly(at)mail.ru
89995897024 watsapp, viber
1. размести датчик около своего вала, подключи питание 5В.
2. возьми у друзей цифровой осцилограф и сними осцилограммы с Q1 и Q2.
3. Выложи их сюда. Желательно на разных скоростях и направлениях вращения.
4. Не скажу за других, но по мне, после этого программа займет 5-10 строчек. Возможно потребуется какая-то обвязка для датчика - посмотрев картинки - я смогу сказать какая.
------
5. Ты должен понимать несовместность условия задачи: "от 0 до..." значит, что нужно определить минимальную скорость вращения. У тебя 10 магнитов на валу - значит 10 импульсов на оборот. Сколько времени ждать импульса? Ровно столько, после остановки вала, будет продолжать гореть твоя лампочка.
------------------------
В предположении "без обвязки" (схема включения из ДШ) и импульс четкий и читаемый на каждый магнит (вот это всё и нужно проверить осцилографом) - код может быть самым простым:
/* * Предполагаем плату Уно или Нано * для ат85 другие пины int0 - PB2, остальные pb0,1,3 */ const byte inQ2 = 2; //speed INT0 const byte inQ1 = 4; // dir const byte outD1 = 5; //на выходах активный 0 const byte outD2 = 6; const uint32_t timeOut = 500; //0.5 сек ждем импульса uint32_t lastChange = 0; void checkRotation(void); void setup() { pinMode (outD1,OUTPUT); digitalWrite (outD1,HIGH); pinMode (outD2,OUTPUT); digitalWrite (outD2,HIGH); attachInterrupt(0,checkRotation,CHANGE); } void loop() { if (millis() - lastChange < timeOut) { byte d = digitalRead(inQ1); // или наоборот, зависит от установки датчика и реле digitalWrite (outD1, d); digitalWrite (outD2,!d); } else { digitalWrite (outD1,HIGH); digitalWrite (outD2,HIGH); } } void checkRotation(void) { lastChange = millis(); }только чтение lastChange в лупе атомизировать неплохо было бы.
from 10000 рублей webserpantin gmail.com
только чтение lastChange в лупе атомизировать неплохо было бы.
эт точно.
Мало - это сколько? Пишите подробности на wrk.sadman@gmial.com , если желаете.
P.S. Это не вы ли с MRTG у меня были?
Завтра отпишусь, сегодня пятница и малость устал... тяжелый день, затем огород, теплица ну и пол литры сэма в догонку.... да и ночь у нас уже поздняя.
Спасибо всем кто откликнулся! Особенно wdrakula и sadman41
Мало - это сколько? Пишите подробности на wrk.sadman@gmial.com , если желаете.
P.S. Это не вы ли с MRTG у меня были?
Задача состоит в следующем, необходимо написать простой скетч для Arduino Nano v3 и ATtiny85
Понимаю, что для знающих людей данная задача не является сколь либо сложной, но сам пока не могу реализовать, ввиду не достаточного опыта программирования ардуин.
А как вы это понимаете, если сами не имете "достаточного опыта" ?
Почему два контроллера ?
А за 1000 р согласен?
А за 1000 р согласен?
и детальки тебе выслать, безвозвратно :)
Быстро скажу, TLE чип персонально имеет определение направление вращение на пин Q1,
стого достаточно просто установка чип триггер логика.
Р е а л и з у е м о - maslachenko767@mail.ru, пишите, пообщаемся
только чтение lastChange в лупе атомизировать неплохо было бы.
поясни пожалуйста
только чтение lastChange в лупе атомизировать неплохо было бы.
поясни пожалуйста
Поясняю: изменение четырёхбайтовой переменной идёт в прерывании, которое может произойти во время чтения этой же переменной в loop(). В результате - до возникновения прерывания считается часть одного значения, а после возврата из обработчика дочитается остаток, но уже другого значения. Проще говоря: байт от значения 15 и три байта от 16. Ну, или с иным раскладом.
только чтение lastChange в лупе атомизировать неплохо было бы.
поясни пожалуйста
Поясняю: изменение четырёхбайтовой переменной идёт в прерывании, которое может произойти во время чтения этой же переменной в loop(). В результате - до возникновения прерывания считается часть одного значения, а после возврата из обработчика дочитается остаток, но уже другого значения. Проще говоря: байт от значения 15 и три байта от 16. Ну, или с иным раскладом.
и как это побороть?
и как это побороть?
https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html - ну или просто noInterrupts(), читаем в локальную переменную из переменной, которая изменяется в прерывании, interrupts(). Ниже - иллюстрация:
volatile uint32_t isrVar = 0; void isr() { isrVar++; } void setup() { Serial.begin(57600); attachInterrupt(digitalPinToInterrupt(2),isr,RISING); } void loop() { noInterrupts(); uint32_t localVar = isrVar; interrupts(); Serial.print(F("isrVar=")); Serial.println(localVar); }и как это побороть?
Может лучше применить небольшой кольцевой буфер, как с работой АЦП по прерыванию и флагом готовности. Все таки запрещать прерывания, мне кажется не очень хорошо.
Бессмысленное усложнение для данной задачи, как по мне. Операции с буфером в блокирующем обработчике могут даже дольше идти, чем атомарный перенос четырех байт.
А чем усложнение чревато ? Ресурсы есть. К тому же если эту задачу расширить до функций энкодера, то самое оно.
Бессмысленное усложнение для данной задачи, как по мне. Операции с буфером в блокирующем обработчике могут даже дольше идти, чем атомарный перенос четырех байт.
Для атомарного чтения именно ПРАВИЛЬНО - блокировать прерывания, в loop() это можно делать просто через cli-sti.
Если прерывание по фронту-спаду, то факт события прерывания будет запомнен и прерывание исполнится, после снятия запрета. Так мы не потеряем событие. Если прерыване по уровню - то событие не "защелкивается", что вобщем-то очевидно.
-----------
В нашей задаче, поскольку время прохода loop() много меньше характерных времен системы и исполнительного устройства (реле),можно вообще не заморачиваться. Если реле неправильно выключится, но в следующем цикле включится... само реле - даже разомкнуться не успеет. Но это неаккуратно. Конечно нужно атомарное чтение.
А чем усложнение чревато ?
А в чём смысл его лепить? Эффективности не добавится, ибо, как wdrakula заметил - всё завязано на релюшке со временем срабатывания в районе 10мс.
Можно, конечно, начать фантазировать на предмет того, что это не релюшка, а быстродействующий ключ, управляющий затвором фотонного излучателя в Большом Андронном Коллайдере и пр. и др.
так и не понял, как сюда добавить атомарное чтение
if (millis() - lastChange < timeOut) {А в чём смысл его лепить?
А какова причина его отсутствия ? Лень ?
А в чём смысл его лепить?
А какова причина его отсутствия ? Лень ?
Двоится...
Брукли, тебя лоджик покусал? Чего говниться на пустом месте-то? Пиши что хочешь туда, хоть классы по Квону.
Да нет. Просто довод "усложнение" не сильно правильный. Пытаюсь понять мотивацию. А она получается "виртуальная". Если ресурсов чипа хватает, то запрещать прерывание некрасиво. Буферизация, мьютексы, семафоры - вот правильные решения, все остальное от лени. Ну на крайняк сделай так, что бы учавствовали только атомарные буфера. Например получай от таймштампа только второй байт или первый. Для этой задачи такого подхода хватит "за глаза".
Што-то я не видел кодов поливалок кактусов с мьютексами. Тоже от лени, наверное. А так бы посидеть недельку, покодить, навернуть с контролем памяти, тройным резервированием релюшек и пр. Штоп не дай бох ленивым не обозвали.
И, да, где-то тут еще честный Си должен промелькнуть.
запрещать прерывание некрасиво.
Я так понимаю, что millis() ты не используешь никогда? (ну и всё остальное в wiring)
Ниже ее код, свеженький, только из wiring.c, там стандартное атомарное чтение 4-х байтовой переменной с запретом прерываний.
unsigned long millis() { unsigned long m; uint8_t oldSREG = SREG; // disable interrupts while we read timer0_millis or we might get an // inconsistent value (e.g. in the middle of a write to timer0_millis) cli(); m = timer0_millis; SREG = oldSREG; return m; }То Логику компилятор не нравиццо, то Архат, не к ночи помянутый, ООП проклинает...Теперь прерывания запрещать нельзя. Может что-то "в консерватории не так"?
запрещать прерывание некрасиво.
Я так понимаю, что millis() ты не используешь никогда? (ну и всё остальное в wiring)
Ниже ее код, свеженький, только из wiring.c, там стандартное атомарное чтение 4-х байтовой переменной с запретом прерываний.
unsigned long millis() { unsigned long m; uint8_t oldSREG = SREG; // disable interrupts while we read timer0_millis or we might get an // inconsistent value (e.g. in the middle of a write to timer0_millis) cli(); m = timer0_millis; SREG = oldSREG; return m; }То Логику компилятор не нравиццо, то Архат, не к ночи помянутый, ООП проклинает...Теперь прерывания запрещать нельзя. Может что-то "в консерватории не так"?
Использую, но не задумывался, что там у него внутри. И это, давайте без фанатизма. Я только озвучил свое мнение. Заметь никому ничего не навязываю, так что мягкое с теплым не путаем.
))Если нужны варианты - тут можно и без millis() и без запретов прерываний, если так уж принциально.)
interrupts()
DIYMan извини, я не думал что мое замечание вызовет столько споров. Ты же знаешь, я посравнению с тобой совсем не программист. Просто жалко стало interrupts(), а вдруг что то произойдет непредвиденное. А то сразу запрещать и не пущать. А о чем тема, наверное уже никто (в том числе и я) не помнит.
interrupts()
DIYMan извини, я не думал что мое замечание вызовет столько споров. Ты же знаешь, я посравнению с тобой совсем не программист. Просто жалко стало interrupts(), а вдруг что то произойдет непредвиденное. А то сразу запрещать и не пущать. А о чем тема, наверное уже никто (в том числе и я) не помнит.
Тут дело простое, пмсм: введение кольцевого буфера взамен атомарного чтения - это эдакий костылёк, который обязательно выстрелит в ногу тогда, когда не ждёшь. Навскидку пример: берём буфер размерностью 2, и запись в буфер из прерывания в 2 раза чаще, чем чтение из него. При таком варианте есть вероятность, что читать будем значение, которое в данный момент изменяется в прерывании. И смысл в том буфере тогда?
Увеличение размера буфера, безусловно, помогает, но только тем, что отдаляет проблему, вместо её решения. Атомарное чтение, пмсм - есть данность, без которой в некоторых случаях просто не обойтись.
Я так вижу, короче.