Помогите с ШИМом.

Мишка
Offline
Зарегистрирован: 09.05.2017

Здравствуйте. Я начинающий ардуинщик. Помогите разобраться: нужно на форсунку подать импульс длительностью 2000мс. Управление минусом. Сам же этот импульс выглядит как меандр прямоугольной формы: 5 мс. Всего 200 импульсов низкого уровня и 200 высокого. Думаю , что цикл надо организовать, но не въеду с чего начать и чем закончить. Пните в нужном направлении. Фото сюда не удалось скинуть.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Мишка пишет:
но не въеду с чего начать и чем закончить. Пните в нужном направлении.
Пинаю!

Начните с изучения любой несложной книжки по программированию, хоть вот этой, а закончите написанием обычного блинка с периодом 10мс на 200 блинков - это и будет то, что Вам нужно.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

А вот мне не понятно:

- Что такое "импульс низкого уровня"

- При чем здесь ШИМ?

 

А фраза "меандр прямоугольной формы" звучит примерно как "окружность круглой формы"

b707
Offline
Зарегистрирован: 26.05.2017

asam пишет:

- При чем здесь ШИМ?

да ладно, чего зря придираться. То что описал ТС - есть ШИМ с частотой 100 Гц и скважностью 50% :)

bizzon
Offline
Зарегистрирован: 29.03.2016

Ну конечно придраться не к чему.

Меандр прямоугольной формы 5 мс длительностью 2000 мс. Чего ж тут неясного.

Берём переменку 50 герц, пускаем через диодный мост - получаем 100 герц, далее триггер шмита с формирователем в 2 секунды. Ардуина не нужна.

bizzon
Offline
Зарегистрирован: 29.03.2016

Не . Так сложно. Два 555 таймера- и можно регулировать и частоту, и длительность.

Гриша
Offline
Зарегистрирован: 27.04.2014

Мишка пишет:
Пните в нужном направлении. Фото сюда не удалось скинуть.

пинаю, пост 1 и 2 этого топика

lean_74
Offline
Зарегистрирован: 22.12.2015

bizzon пишет:

Не . Так сложно. Два 555 таймера- и можно регулировать и частоту, и длительность.

а на#рена два?

bizzon
Offline
Зарегистрирован: 29.03.2016

А как же 2 секунды?

 

lean_74
Offline
Зарегистрирован: 22.12.2015

так все равно длительность подбирать RC цепочкой, хватит и одной 555, еще один кондер после зарядки 2сек, тормозит работу.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

bizzon пишет:

А как же 2 секунды?

На каждую секунду своя 555-ая? :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Может так, если я правильно понял ТС?
Если полярность обратная сменить HIGH на LOW
 

void setup() {
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  forsunka();
  
}

void forsunka(){
  for( int i=1; i<=400; i++){
    delay(5);
    digitalWrite(11,!digitalRead(11));
 }
 digitalWrite(11,HIGH);
}
void loop() { 
}

 

Мишка
Offline
Зарегистрирован: 09.05.2017

ua6em пишет:

Может так, если я правильно понял ТС?
Если полярность обратная сменить HIGH на LOW
 

void setup() {
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  forsunka();
  
}

void forsunka(){
  for( int i=1; i<=400; i++){
    delay(5);
    digitalWrite(11,!digitalRead(11));
 }
 digitalWrite(11,HIGH);
}
void loop() { 
}

 


Благодарю. Сегодня вечером буду пробовать.

b707
Offline
Зарегистрирован: 26.05.2017

bizzon пишет:

Не . Так сложно. Два 555 таймера- и можно регулировать и частоту, и длительность.

ребята, у нас тут программисткий форум :) Делать на аппаратных таймерах то, что можно сделать ногодрыгом - это ОФФТОП для этого сайта :)

SLKH
Offline
Зарегистрирован: 17.08.2015

ua6em пишет:

Может так, если я правильно понял ТС?
Если полярность обратная сменить HIGH на LOW
 

void setup() {
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  forsunka();
  
}

void forsunka(){
  for( int i=1; i<=400; i++){
    delay(5);
    digitalWrite(11,!digitalRead(11));
 }
 digitalWrite(11,HIGH);
}
void loop() { 
}

 

tone(pin, 100, 2000); - не?

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:

ребята, у нас тут программисткий форум :) Делать на аппаратных таймерах то, что можно сделать ногодрыгом - это ОФФТОП для этого сайта :)

С одной стороны, согласен, с другой, сам иногда советую, не маяться х-ей, а просто поставить выключатель и т.п.. В данной задаче, в ардуине, есть хоть какое-то разумное зерно. ИМХО.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

b707 пишет:

ребята, у нас тут программисткий форум :) Делать на аппаратных таймерах то, что можно сделать ногодрыгом - это ОФФТОП для этого сайта :)

Во! Пральна! Родная душа нашлась! А то тут, блин, некоторые наезжают, что я мол интеграл программно считаю, вместо того, чтобы интегрирующую цепочку ставить :(

bizzon
Offline
Зарегистрирован: 29.03.2016

Таки уговорили- давайте поногодрыгаем. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

SLKH пишет:

ua6em пишет:

Может так, если я правильно понял ТС?
Если полярность обратная сменить HIGH на LOW
 

void setup() {
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  forsunka();
  
}

void forsunka(){
  for( int i=1; i<=400; i++){
    delay(5);
    digitalWrite(11,!digitalRead(11));
 }
 digitalWrite(11,HIGH);
}
void loop() { 
}

 

tone(pin, 100, 2000); - не?

ТС попросил - Думаю , что цикл надо организовать

SLKH
Offline
Зарегистрирован: 17.08.2015

ua6em пишет:

SLKH пишет:

ua6em пишет:

Может так, если я правильно понял ТС?
Если полярность обратная сменить HIGH на LOW
 

void setup() {
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  forsunka();
  
}

void forsunka(){
  for( int i=1; i<=400; i++){
    delay(5);
    digitalWrite(11,!digitalRead(11));
 }
 digitalWrite(11,HIGH);
}
void loop() { 
}

 

tone(pin, 100, 2000); - не?

ТС попросил - Думаю , что цикл надо организовать

дык... в tone.cpp этих циклов есть, уже организованных.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

SLKH пишет:

ua6em пишет:

SLKH пишет:

ua6em пишет:

Может так, если я правильно понял ТС?
Если полярность обратная сменить HIGH на LOW
 

void setup() {
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  forsunka();
  
}

void forsunka(){
  for( int i=1; i<=400; i++){
    delay(5);
    digitalWrite(11,!digitalRead(11));
 }
 digitalWrite(11,HIGH);
}
void loop() { 
}

 

tone(pin, 100, 2000); - не?

ТС попросил - Думаю , что цикл надо организовать

дык... в tone.cpp этих циклов есть, уже организованных.

Так оно может и есть, только ТС на форуме с 2017 года и никак не одолеет простейшие скетчи, надо помочь разобраться )))

Мишка
Offline
Зарегистрирован: 09.05.2017

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

const int FORSA = 11;
const int BUTTON = 2;

void setup() {
 pinMode(FORSA,OUTPUT);
 pinMode(BUTTON,INPUT);

}

void loop() {
 if (digitalRead(BUTTON)==LOW) 
 {
  digitalWrite(FORSA,LOW); 
 }
else
{
  tone (FORSA,100,2000);
}
}

сигнал постоянно идет(шим) и сетодиод горит. Как сделать, что бы время нажатия кнопки не влияло на продолжительность сигнала?

andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015

Мишка пишет:
Как сделать, что бы время нажатия кнопки не влияло на продолжительность сигнала?

Ловите не состояние кнопки, а ее переход их одного состояния в другое.

Гриша
Offline
Зарегистрирован: 27.04.2014

andriano пишет:

Мишка пишет:
Как сделать, что бы время нажатия кнопки не влияло на продолжительность сигнала?

Ловите не состояние кнопки, а ее переход их одного состояния в другое.

и запускайте таймер по нужному переходу или ставьте флаг

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Гриша пишет:

andriano пишет:

Мишка пишет:
Как сделать, что бы время нажатия кнопки не влияло на продолжительность сигнала?

Ловите не состояние кнопки, а ее переход их одного состояния в другое.

и запускайте таймер по нужному переходу или ставьте флаг

Видно же, что с логикой у ТС совсем не очень, надо пнуть в нужном направлении, так как следующим шагом будет вопрос, что опять работает наоборот )))
 

#define NOT_SHIM LOW
const int FORSA = 11;
const int BUTTON = 2;
int flag = 0;

void setup() {
 pinMode(FORSA,OUTPUT);
 pinMode(BUTTON,INPUT_PULLUP);
 digitalWrite(FORSA,NOT_SHIM ); 
}

void loop() {
 if (digitalRead(BUTTON)==LOW && flag == 0) 
 {
  flag = 1; tone (FORSA,100,2000); delay(2000); digitalWrite(FORSA,NOT_SHIM ); 
  }
  
 if (digitalRead(BUTTON)==HIGH && flag == 1) {   flag = 0;  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

tone() неблокирующий. Если после него сразу поставить digitalWrite(), то фокус неполучится.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

tone() неблокирующий. Если после него сразу поставить digitalWrite(), то фокус неполучится.

кошмарр )))
ну не вводить жеж отслеживание через миллис, тогда уж лучше через цикл или добавить брокирующий delay(2000)

ЗЫ я поправил выше код, благодарю!

Через цикл, код на 600 байт меньше )))
 

#define NOT_SHIM LOW
const int FORSA = 11;
const int BUTTON = 2;
int flag = 0;

void setup() {
 pinMode(FORSA,OUTPUT);
 pinMode(BUTTON,INPUT_PULLUP);
 digitalWrite(FORSA,NOT_SHIM ); 
}

void forsunka(){
  for( int i=1; i<=400; i++){
  digitalWrite(FORSA,!digitalRead(FORSA));
  delay(5);
 }
  digitalWrite(FORSA,NOT_SHIM); 
}

void loop() {
 if (digitalRead(BUTTON)==LOW && flag == 0) 
 {
 // flag = 1; tone (FORSA,100,2000); delay(2000); digitalWrite(FORSA,NOT_SHIM ); 
  flag = 1; forsunka(); 
  }
  
 if (digitalRead(BUTTON)==HIGH && flag == 1) {   flag = 0;  }
}

 

SLKH
Offline
Зарегистрирован: 17.08.2015

sadman41 пишет:

tone() неблокирующий. Если после него сразу поставить digitalWrite(), то фокус неполучится.

Что хорошего в блокирующем цикле?

============================
startTimeFors = millis();
tone(forsPin, 100);
/* занимаемся своими делами*/
if (millis()-startTimeFors > 2000) { noTone(forsPin); digitalWrite(forsPin, HIGH); }
============================
sadman41
Онлайн
Зарегистрирован: 19.10.2016

Понятия не имею, что в нём хорошего или плохого. В данной ситуации вообще по-барабану какой он.

Я написал про то, что конструкция tone(pin, freq, duration) не будет вести себя ожидаемо, если сразу после неё вызвать digitalWrite(pin), а не про циклы.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

Я написал про то, что конструкция tone(pin, freq, duration) не будет вести себя ожидаемо, если сразу после неё вызвать digitalWrite(pin), а не про циклы.

и я поправил код, так как понятия не имел о функции tone(), а в данном случае блокирующие или неблокирующие функции ТС безразлично, так как ничего другого, кроме выдать пачку импульсов при нажатии кнопки не требуется, как говорит главный по целебату в России, будет другая неделя будут другие новости )))

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Я бы вообще этот луп в четыре блокирующих строчки написал. Если, конечно, tone() канает.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

 Если, конечно, tone() канает.

а вот в этом я не уверен ))) поэтому и привёл пример с циклом, там количество импульсов можно скорректировать

 

Мишка
Offline
Зарегистрирован: 09.05.2017

ua6em пишет:

Гриша пишет:

andriano пишет:

Мишка пишет:
Как сделать, что бы время нажатия кнопки не влияло на продолжительность сигнала?

Ловите не состояние кнопки, а ее переход их одного состояния в другое.

и запускайте таймер по нужному переходу или ставьте флаг

Видно же, что с логикой у ТС совсем не очень, надо пнуть в нужном направлении, так как следующим шагом будет вопрос, что опять работает наоборот )))
 

#define NOT_SHIM LOW
const int FORSA = 11;
const int BUTTON = 2;
int flag = 0;

void setup() {
 pinMode(FORSA,OUTPUT);
 pinMode(BUTTON,INPUT_PULLUP);
 digitalWrite(FORSA,NOT_SHIM ); 
}

void loop() {
 if (digitalRead(BUTTON)==LOW && flag == 0) 
 {
  flag = 1; tone (FORSA,100,2000); delay(2000); digitalWrite(FORSA,NOT_SHIM ); 
  }
  
 if (digitalRead(BUTTON)==HIGH && flag == 1) {   flag = 0;  }
}

 

ua6em, большое спасибо ! Вот этот скетч работает. Я конечно же не написал бы его. Разбирался как он работает долго. )Теорию буду читать. А второй не работает. Ну и ладно.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Мишка пишет:

#define NOT_SHIM LOW
const int FORSA = 11;
const int BUTTON = 2;
int flag = 0;

void setup() {
 pinMode(FORSA,OUTPUT);
 pinMode(BUTTON,INPUT_PULLUP);
 digitalWrite(FORSA,NOT_SHIM ); 
}

void loop() {
 if (digitalRead(BUTTON)==LOW && flag == 0) 
 {
  flag = 1; tone (FORSA,100,2000); delay(2000); digitalWrite(FORSA,NOT_SHIM ); 
  }
  
 if (digitalRead(BUTTON)==HIGH && flag == 1) {   flag = 0;  }
}

 

 

ua6em, большое спасибо ! Вот этот скетч работает. Я конечно же не написал бы его. Разбирался как он работает долго. )Теорию буду читать. А второй не работает. Ну и ладно.

да нет тут никакой теории, по шагам:
1. назначаем пин на выход ШИМ
2. назначаем пин на кнопку, включаем подтягивающий резистор, на пине будет 1, пока кнопка не притянута к земле.

в теле программы:
1.Читаем состояние кнопки и флага, что нажатия кнопки еще не было, если есть нажатие то
2. выставляем флаг, что было нажатие кнопки, шимим 2 секунды, так как процедура неблокирующая (скажите Садману спасибо, не знал) ждём эти 2 секунды, для определённости состояния переводим пин ШИМ в выключено.
3. Читаем состояние кнопки, если отжата и был выставлен флаг нажатия кнопки, сбрасываем флаг

Далее крутимся в цикле ожидая следующего нажатия кнопки, то есть, второй и последующие разы запустить процедуру для форсунки, надо сначала отжать кнопку, а потом снова нажать

)))