Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить

Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 11:42:03

Есть Атмега328 с прошитым загрузчиком (16мгц). Я затеял управление лампой на радиомодуле
Использую RemoteReceiver.h

Проблема в ттом, что я бы хотел сделать плавное включение и выключения. Для этого использую функцию Delay, но она в моей коде работает некоректно.
Т.е ставлю Делэй(500) и зная что 255*0,5 будет 125 сек, а цикл проходит за 1.5 сек.
Понимаю что, функция void showCode() завязана где то на прерывании, так как радиомодуль подключен к 4 ноге ардуино (Int0).Может быть в этом проблема.
создал подобный вопрос на http://arduino.ru/forum/programmirovani ... rovka-shim но там так и не смогли мне помочь.
Даю весь код

Код:
// include the library code:
#include <LiquidCrystal.h>
#include <RemoteReceiver.h>
#include <avr/eeprom.h>

// initialize the library with the numbers of the interface pins
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(12, 11, 5, 4, 6, 7);
//const unsigned long receivedCode=0;
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  //lcd.print("hello, world!");
 //Connect the receiver to digital pin 2.-пин 2.это вход для Радиоприёмника
  RemoteReceiver::init(0, 3, showCode);
  pinMode(8, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(9, OUTPUT);  //шим на выход, там частот около 1кгц
  // Пины D9 и D10 - 31.4 кГц (Переопределяем частоту ШИМ)
  TCCR1A = 0b00000001;  // 8bit
  TCCR1B = 0b00000001;  // x1 phase correct
}

void showCode(unsigned long receivedCode, unsigned int period)

  lcd.clear();
  lcd.print(":");
  lcd.print(receivedCode);
  lcd.print(",p:");
  lcd.print(period);
 
int AR6;
int AR;
   // on
  if (receivedCode==66100) 

    AR6 =eeprom_read_byte(0);
   //AR6=255;
    AR=0;
  while (AR<=AR6)
  {
      analogWrite(9, AR);
      AR=AR+1;
      //delay(500);
       lcd.setCursor(0, 1);
        lcd.print(AR);
      }
}
   // off
  if (receivedCode==66132) 
{
     AR6 =eeprom_read_byte(0);
      do {
      analogWrite(9, AR6);
      AR6=AR6-1;
      delay(500);
       lcd.setCursor(0, 1);
        lcd.print(AR6);
      } while (AR6>0)
  ;
  }
  // ступенчатое увеличение яркости
   if (receivedCode==66099) 
   {
      lcd.setCursor(0, 1);
      lcd.print(AR6);
      AR6 =eeprom_read_byte(0);     
         AR6=AR6+20;
        if (AR6>255) {AR6=255;}//
        analogWrite(9, AR6);  //  якрость
        eeprom_write_byte(0,AR6);     
      lcd.setCursor(0, 1);
      lcd.print(AR6);
   }
   // ступенчатое уменьшение яркости
   if (receivedCode==66105) 
   {
      AR6 =eeprom_read_byte(0);     
       AR6=AR6-20;
      if (AR6<10) {AR6=10;}// ничего не делаем - яркость минимальная
      analogWrite(9, AR6);  //  якрость
      eeprom_write_byte(0,AR6);     
      lcd.setCursor(0, 1);
      lcd.print(AR6);
    }
 
 }

void loop() {
}

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 13:45:46

У вас delay() вызывается только в одном случае, когда if (receivedCode==66132).
И сдается мне, что колбэк showCode() вызывается только раз, когда приходит новый код. Что вообще на LCD вывод в этом случае показывает? Уменьшается плавно ваше AR6 или как?

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 15:03:31

Что вообще на LCD вывод в этом случае показывает? Уменьшается плавно ваше AR6 или как?


да, ЛСД показывает что уменьшает плавно. Но скорость уменьшения очень быстрая. Скорость не соответсвует значению в Делэй().

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 15:10:01

Значит наверное RemoteReceiver::init вешает колбэк showCode() на прерывание. И пока у вас с 1го срабаывания работает delay() уже вызывается новое прерывание и повторно ф-я showCode() еще до окончания прошлого delay().
Чтобы это проверить, попробуйте так поменять кусок кода с delay():
Код:
  if (receivedCode==66132)
{
     AR6 =eeprom_read_byte(0);
      do {
      analogWrite(9, AR6);
      AR6=AR6-1;
      cli();
      delay(500);
      lcd.setCursor(0, 1);
      lcd.print(AR6);
      sei();
      } while (AR6>0)
  ;
  }

Но это не хорошо так делать. Вообще длительные задержки в прерывании - зло. Но проверить сойдет, чтобы не лезть в исходники RemoteReceiver

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 15:11:09

но вставка сама по себе Дэлей() с любым значением приводи к плавному 1.5 секунднгму гашению/разгорнию.
Без Дэлей() светодиод вспыхивает без задержки.


Ок. попробую. Отпишусь!!!!

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 15:16:52

но вставка сама по себе Дэлей() с любым значением приводи к плавному 1.5 секунднгму гашению/разгорнию.
Без Дэлей() светодиод вспыхивает без задержки.

Ну так без delay() у вас там цикл, который конечно же пробегает моментально. А тут когда срабатывает прерывание по приходу нового кода.

Вообще правильно когда сработало прерывание - проверили код и в некую переменную записали себе что было нажато и в какое состояние мы переходим. А уже затем в цикле loop() если значение этой переменной равно нужному действию - там плавно и гасим. Тогда новые прерывания не будут мешать.

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 17:07:11

NStorm писал(а):ообще правильно когда сработало прерывание - проверили код и в некую переменную записали себе что было нажато и в какое состояние мы переходим. А уже затем в цикле loop() если значение этой переменной равно нужному действию - там плавно и гасим. Тогда новые прерывания не будут мешать.


вот это мне и нужно. Спасибо. буду пробовать так организовать совй код. Пока правда мысле нет. Надо сосредоточиться


p..s.
c остановками прерывание по cli и sei ничего не вышло. Все осталось попреженму

счас еще ради смеха протестирую
for(int m=0; m<100;m++)
{
delay(100);
lcd.setCursor(0, 1);
lcd.print(AR);
}

и буду делать нормаьлно.

Добавлено after 2 minutes 29 seconds:
вот это получилось
for(int m=0; m<100;m++)
{
delay(100);
lcd.setCursor(0, 1);
lcd.print(AR);
}
работате с непонятно задержкой правда, но медленно

Добавлено after 1 hour 19 seconds:
все переписал под loop, списибо

NStorm, как так получается что я пишу
eeprom_write_byte(0,255);

а в память ложиться ff. Это такая фишка среды ардуино,что бы я не волновался?

Добавлено after 1 minute 17 seconds:
то же самое и при чтении из еепрома!

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 18:46:26

NStorm, как так получается что я пишу
eeprom_write_byte(0,255);

а в память ложиться ff. Это такая фишка среды ардуино,что бы я не волновался?

Так 255 и есть 0xFF, всё верно.

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 20:52:45

ну я то пишу десятичное значение, а он как то его таво... в хекс перекладывает?

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 21:49:11

Это во "внутренностях функции" упрятано - Си не ассемблер, как привести в реальный набор команд решает сам компилятор.
Простому пользователю те "дебри" особо не требуются.
Во встроенной (off-line) помощи ардуиноIDE есть все необходимые примеры по базовым функциям.
( C:\Program Files\Arduino\reference\www.arduino.cc\en\Reference запустить файл HomePage.html )
:hunger:
А вот "расширенные" уже потребуют подключения к инету...
:(

Re: Ардуино. Включение, выключение, регулировка ШИМ

Пт окт 02, 2020 23:58:12

т.е получается что если я ему float с плавающей точкой "скормлю" в память, он (Ардуин) мне без труда оттуда в том самом виде вернет?
Надо попробовать! То.есть и память сам распределит и на байты этот число нашинкует?

Добавлено after 1 minute 33 seconds:
Удобно, конечно, если это так.

Re: Ардуино. Включение, выключение, регулировка ШИМ

Сб окт 03, 2020 00:21:06

Задача какая ?
olegue писал(а):Есть Атмега328

olegue писал(а):я бы хотел сделать плавное включение и выключения. Для этого использую функцию Delay

Для плавное включение и выключения в Атмега328 есть аж целых 3 таймера !
Screenshot_1.jpg
(56.78 KiB) Скачиваний: 264

Two 8-bit Timer позволяет плавно включать и выключать лампу с шагом 0...255.
One 16-bit Timer позволяет плавно включать и выключать лампу с шагом 0...65535.
olegue писал(а):управление лампой на радиомодуле

По радио модулям можно глянуть у нас - https://www.radiokot.ru/forum/viewtopic ... 8&t=148087
Сейчас там делаем Умный Дом... с лампочками))

Re: Ардуино. Включение, выключение, регулировка ШИМ

Сб окт 03, 2020 08:25:41

вот это получилось
for(int m=0; m<100;m++)
{
delay(100);
lcd.setCursor(0, 1);
lcd.print(AR);
}
работате с непонятно задержкой правда, но медленно


а что если задержку сделать так...




вес код выполняется ,а когда приходит время наше условие исполнится или несколько условий :))

http://arduino.ru/Reference/Millis

Re: Ардуино. Включение, выключение, регулировка ШИМ

Сб окт 03, 2020 11:06:39

...
Для плавное включение и выключения в Атмега328 есть аж целых 3 таймера !
Screenshot_1.jpg

Two 8-bit Timer позволяет плавно включать и выключать лампу с шагом 0...255.
One 16-bit Timer позволяет плавно включать и выключать лампу с шагом 0...65535....


Это при работе под ассемблером или Си "в чистом виде" - при работе в рамках референса ардуиноIDE необходимо учитывать его особенности применения.
Там таймеры участвуют в определенных системных функциях.
Посему при фривольном их использовании могут иметь место "нежданчики" довольно сложного происхождения.
Собственно там также Си да еще и с добавкой С++... НО... имеют место и дополнительные функции из встроенных библиотек - нечто вроде базового БИОС/ОС, в которых уже задействуются аппаратные ресурсы МК.
Работу с "DIP-микросборкой" упрощают, но добавляют своей специфики.
Данные о тех "нюансах" к сожалению приходится по разным источникам самому выискивать.
Вот, к примеру, одна цитатка из не помню уже какой(чьей) книжи -
("добавка", которую надо учитывать работая с самодельными функциями внешних прерываний):
"...
внутри функции обработки прерывания не работает функция delay(), значения, возвращаемые функцией millis(), не изменяются.
Возможна потеря данных, передаваемых по последовательному соединению (Serial data) в момент выполнения функции обработки прерывания.
Переменные, изменяемые в функции, должны быть объявлены как volatile.
..."
8)
Кстати...
у адуринки весьма неплохой симулятор имеется (UNO V3, megaV3):
https://radiokot.ru/forum/viewtopic.php ... 5#p3901095
Работает на компах начиная с ХР sp3 и выше
Да еще и "стандартную" внешнюю обвязку симулирует...
:wink:

Re: Ардуино. Включение, выключение, регулировка ШИМ

Сб окт 03, 2020 13:13:19

ну я то пишу десятичное значение, а он как то его таво... в хекс перекладывает?

А какая "ему" разница? Данные хранятся всё-равно в двоичном виде. 0 и 1. Как показывать их - это уже вопрос чисто отображения.

Re: Ардуино. Включение, выключение, регулировка ШИМ

Сб окт 03, 2020 13:35:13

Это вопрос синтаксиса компилятора.
Смотрим в оффлайн/онлайн хэлпе описание функции и допустимые для нее типы/границы переменных.
8)

Re: Ардуино. Включение, выключение, регулировка ШИМ

Сб окт 03, 2020 15:43:12

BOB51 писал(а):Это при работе под ассемблером или Си "в чистом виде" - при работе в рамках референса ардуиноIDE необходимо учитывать его особенности применения...

Вот поэтому у меня нет Ардуины. И никогда не было ))

Re: Ардуино. Включение, выключение, регулировка ШИМ

Вс окт 04, 2020 08:08:53

"Ардуиноподобные" всего лишь один из видов элементной базы, содержащих различные МК и сопутствующую периферию.
Выполняются в виде платок формата "DIP-микросборка". Могут содержать как AVR (самые первые) так и ARM, ESP8266 и иные МК или микропроцессоры. Обрабатываются как обобщенной IDE (arduino IDE), так и любыми известными пользователю средами, применяемыми в отношении установленных на платках МК.
Однако обладают "двойственностью" в правилах применения:
1. можно использовать как DIP-микросборку и создавать программу в рамках референса ардуиноIDE
2. нужно достать схему конкретной платки и работать с установленными на ней компонентами под ассемблером или Си.
Оба варианта одинаково применимы - но во втором случае надо поднимать гораздо больше документации, ибо на платках не только один МК устанавливается.
:wink:
В то же время стиль программирования в каждом случае будет заметно отличаться. В первом - это ближе к обработке данных и связи с внешней "периферией с мозгами" с применением протоколов последовательного обмена плюс частичное управление "лаподрыгом". А уж прикладное применение в обработке данных делают внешние СБИС (специализированные или на основе самоделок на МК). Требует от программиста соблюдения некоторых самоограничений, как платы за "универсальность подхода" к различным МК.
Во втором - это обычная работа с МК, правда с учетом уже выполненного фрагмента схемы минимальной обвязки, который имеется на платке адуринки.
Тут все зависит от желания и целей автора проекта.
8)
Ответить