Счётчик импульсов

bit
Offline
Зарегистрирован: 07.05.2012

Привет всем суть кода такова, нажимаем кнопку на 11 pin включается светодиод 10 pin индикатор и запускается двигатель, срабатывает датчик на 7 pin  включается светодиод 9   отсчитываются импульсы с шестерни 6 pin , отсчитали 4 импульса 10 pin выкл. светодиод гаснет двигатель стоп.

 

Но почему та светодиод после отсчёта импульсов не гаснет 10 pin

В чём проблема подскажите

 

int regim=1; 
 int flag=0; 
 
 
 int knopka=0;



 void setup()   
 { 
  
  pinMode(8, OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT); //
  pinMode(11,INPUT);
  
      
      
 
 } 

 void loop() 

 { 
       
     if(digitalRead(11)==HIGH&&flag==0)//если кнопка нажата   
    
     { 
       regim++;   
       flag=1; 
         
      
          
        if(regim>2)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                
        } 
       
     } 
       
      if(digitalRead(11)==LOW&&flag==1)//если кнопка НЕ нажата 
    
     { 
          
        flag=0;//обнуляем переменную  
     } 
      
       
       
    if(regim==1)//первый режим 
    { 
           digitalWrite(10,LOW); //светодиод выключен двигатель OFF
        
        
     
    } 
    if(regim==2)//второй режим, нажали и отпустили кнопку
    { 
      digitalWrite(10,HIGH);//включился светодиод – двигатель ON
     
  if(digitalRead(7)==HIGH)//если датчик высокий уровень
 { 
 digitalWrite(9,HIGH);//включаем светодиод 
 
   if(digitalRead(6)==HIGH)// Отчитываем 4 импульса
  
  {
    knopka++;
    delay(200);
    digitalWrite(8,HIGH);    //мигаем светодиодам после каждого импульса
    delay(1);
    digitalWrite(8,LOW);
    
  }
   if(knopka>=4)  //  4 импульса
  
  {
    digitalWrite(10,LOW); после 4 импульсов гасим светодиод – отключаем двигатель
    
  }
 } 
 else//если не нажата... 
 { 
 digitalWrite(9,LOW);//выключаем 
 } 
   
     
  
  } 
      
   
  
      
 } 

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

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

и еще, в подробности не вникал, но вот-так

if(digitalRead(6)==HIGH)// Отчитываем 4 импульса
{
knopka++;

никто не считает, т.к. если двигатель будет вращаться медленно, то он за один HIGH может насчитать 100500 раз.

bit
Offline
Зарегистрирован: 07.05.2012

Подскажите пожалуйста как мне этот бардак исправить

И с счётчикам да у меня там косяк

Snubist
Offline
Зарегистрирован: 18.02.2013

Счетчик по фронту ипульсов

OldImpuls=Impuls;
if(digitalRead(6)==HIGH){
  Impuls=true;
  digitalWrite(8,HIGH);
  }
  else{
   Impuls=false;
   digitalWrite(8,LOW);
  } 
if (Impuls && !OldImpuls){
  knopka++;
  }

 

Не забываем вначале объявить переменные 

boolean Impuls, OldImpuls;
int knopka;

 

bit
Offline
Зарегистрирован: 07.05.2012

Это выход импульсов с оптического датчика вращения двигателя + 4.6v высокий уровень +0.57v низкий уровень я его подключаю к цифровому входу ардуино

 

14.00kHz

bit
Offline
Зарегистрирован: 07.05.2012

 

Сейчас попробую

bit
Offline
Зарегистрирован: 07.05.2012

Подскажите как мне его выключить 10 пин после отсчёта 4 импульсов не могу сообразить

 


boolean Impuls, OldImpuls;
int knopka;

int regim=1; 
 int flag=0; 
 
 




 void setup()   
 { 
  
  pinMode(8, OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT); //
  pinMode(11,INPUT);
  
      
      
 
 } 

 void loop() 

 { 
       
     if(digitalRead(11)==HIGH&&flag==0)//если кнопка нажата   
    
     { 
       regim++;   
       flag=1; 
         
      
          
        if(regim>2)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                
        } 
       
     } 
       
      if(digitalRead(11)==LOW&&flag==1)//если кнопка НЕ нажата 
    
     { 
          
        flag=0;//обнуляем переменную  
     } 
      
       
       
    if(regim==1)//первый режим 
    { 
           digitalWrite(10,LOW); //светодиод выключен двигатель OFF
        
        
     
    } 
    if(regim==2)//второй режим, нажали и отпустили кнопку
    { 
      digitalWrite(10,HIGH);//включился светодиод – двигатель ON
     
  if(digitalRead(7)==HIGH)//если датчик высокий уровень
 { 
 digitalWrite(9,HIGH);//включаем светодиод 
 
  OldImpuls=Impuls;
if(digitalRead(6)==HIGH){
  Impuls=true;
  digitalWrite(8,HIGH);
  }
  else{
   Impuls=false;
   digitalWrite(8,LOW);
  } 
if (Impuls && !OldImpuls){
  knopka++;
  }
   if(knopka>=4)  //  4 импульса
  
  {
    digitalWrite(10,LOW); //после 4 импульсов гасим светодиод – отключаем двигатель
    
  }
 } 
 else//если не нажата... 
 { 
 digitalWrite(9,LOW);//выключаем 
 } 
   
     
  
  } 
      
   
  
      
 } 

 

Snubist
Offline
Зарегистрирован: 18.02.2013

А так?

boolean Impuls, OldImpuls;
int knopka;

int regim=1; 
int flag=0; 

void setup()   
{ 
  pinMode(8, OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT); //
  pinMode(11,INPUT);
} 

void loop() 

{ 

  if(digitalRead(11)==HIGH&&flag==0)//если кнопка нажата   
  { 
    regim++;   
    flag=1; 
    if(regim>2)//ограничим количество режимов 
    { 
      regim=1;//так как мы используем только одну кнопку, 
    } 
  } 
  if(digitalRead(11)==LOW&&flag==1)//если кнопка НЕ нажата 
  { 
    flag=0;//обнуляем переменную  
  } 



  if(regim==1)//первый режим 
  { 
    digitalWrite(10,LOW); //светодиод выключен двигатель OFF
  } 
  if(regim==2)//второй режим, нажали и отпустили кнопку
  { 
    digitalWrite(10,HIGH);//включился светодиод – двигатель ON
    if(digitalRead(7)==HIGH)//если датчик высокий уровень

    { 
      digitalWrite(9,HIGH);//включаем светодиод 
      OldImpuls=Impuls;  // Запоминаем состояние предыдущего импульса
      if(digitalRead(6)==HIGH) //Если лог 1
      {
        Impuls=true;    //то запоминаем
        digitalWrite(8,HIGH); // и включаем светодиод
      }
      else  //иначе
      {
        Impuls=false; // запоминаем 0
        digitalWrite(8,LOW); //выключаем светодиод
      } 
      if (Impuls && !OldImpuls)  //Если текущий импульс 1, а предыдущий 0
      {
        knopka++;  //Считаем импульсы
      }
      if(knopka>=4)  //  4 импульса

      {
        digitalWrite(10,LOW); //после 4 импульсов гасим светодиод – отключаем двигатель
        regim==1;  //Сбрасываем режим
        knopka=0;  //Сбрасываем счетчик импульсов
      }
    } 
    else//если не нажата... 
    { 
      digitalWrite(9,LOW);//выключаем 
    } 
  } 
} 

 

bit
Offline
Зарегистрирован: 07.05.2012

Привет наконец время появилась для продолжения своего проекта.

Пытаюсь переделать струйный принтер в планшетный поменял вал подачи бумаги на резьбовую передачу  , теперь чтобы сместить лист бумаги на 5мм мне нужна вал провернуть на 1об , а на принтере 5мм на четверть оборота получается

 

Подскажите как мне сделать чтобы ардуина скажем 3 импульса считывал, а 4 отправлял на контроллер принтера?

bit
Offline
Зарегистрирован: 07.05.2012

А хотя нет как то вот так должно быть

 

Подскажите пожалуйста как можно это реализовать

__Alexander
Offline
Зарегистрирован: 24.10.2012

легче всего по внешнему прерыванию.

bit
Offline
Зарегистрирован: 07.05.2012

Вот попробовал так , подключился к оптическому датчику принтера , входящий и исходящий сигнал без искажений

int ledPin = 13;               
int btnPin = 12;                
int val=0;

void setup()                     
{
  pinMode(ledPin, OUTPUT);      
  pinMode(btnPin, INPUT);      
          
}

void loop()                      
{
  val = digitalRead(btnPin);    // узнаём состояние кнопки
  if(val==HIGH)                 // кнопка нажата
  {
    digitalWrite(ledPin, HIGH); // зажигаем светодиод
  
  }
  else                          // кнопка не нажата
  {
    digitalWrite(ledPin, LOW);  // гасим светодиод
   
  }
 
}

 

 

Подскажи пожалуйста как мне изменить исходящий сигнал с ардуино?

Чтобы он  примерно вот такой был?

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

ардуина какая?

bit
Offline
Зарегистрирован: 07.05.2012

 

Ардуина на Атмеге8 и на Атмеге328   самодельные

__Alexander
Offline
Зарегистрирован: 24.10.2012

Оно?

 

если да, то вот... прерывание INT0 (PORTD2 на 328-й) настраиваем на "по изменению уровня" и считаем. Единственное я не знаю как оно будет работать при неизвестном начальном состоянии. Проверте.

Да, и обнулять флаг прерывания (EIFR = 0xFF; или EIFR = (1 << INTF0);) надо обязательно, т.к. оно всегда сработает при старте, т.к. выбран такой режим. Либо настроить его по переднему фронту, а после первого срабатывания перенастроить на текущий.

#include <avr\interrupt.h>

char count = 0, mode = 0;
char ledPin = 13;  
// the setup routine runs once when you press reset:
void setup() {                
DDRD &= 0xFB;
PORTD &= 0xFB;
pinMode(ledPin, OUTPUT); 

mode = 0;
count = 0;

EICRA = (1 << ISC00);
EIFR = 0xFF;
EIMSK = (1 << INT0);
asm("sei"); 

}

// the loop routine runs over and over again forever:
void loop() 
{
}


ISR(INT0_vect) { /* signal handler for external interrupt int0 */
switch(mode)
{
  case 0:
  
  count++;
    if (count < 3) { digitalWrite(ledPin, LOW); }
    else {count = 0; digitalWrite(ledPin, HIGH); mode = 1; }

  break;
  
  case 1:
  count++;
    if (count < 3) { digitalWrite(ledPin, HIGH); }
    else {count = 0; digitalWrite(ledPin, LOW); mode = 0; }
  break;
 
} // switch

   }

 

bit
Offline
Зарегистрирован: 07.05.2012

Вроде бы оно спасибо , сейчас попробую, вот тока библиотеку  отрою где нить

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

какую библиотеку?

bit
Offline
Зарегистрирован: 07.05.2012

 

Да он у меня ругается

 

 

 

sketch_may07f:13: error: 'EICRA' was not declared in this scope

sketch_may07f:14: error: 'EIFR' was not declared in this scope

sketch_may07f:15: error: 'EIMSK' was not declared in this scope

 

bit
Offline
Зарегистрирован: 07.05.2012

 

Я просто в этом деле новичок

 

bit
Offline
Зарегистрирован: 07.05.2012

 

Блин у меня Атмега 8 стояла )))

bit
Offline
Зарегистрирован: 07.05.2012

 

Я почему та на Атмеге 1280 не могу этот вход найти (прерывание INT0 (PORTD2 на 328-й)

bit
Offline
Зарегистрирован: 07.05.2012

pin21

bit
Offline
Зарегистрирован: 07.05.2012

Всё заработало спасибо ещё раз)))

bit
Offline
Зарегистрирован: 07.05.2012

Привет всем, делаю эмулятор сигнала вращения вала подачи бумага на принтер чтобы он в ошибку не вставал

 

Суть кода такова вал крутится в перед крутится в назад

 

Вот код по отдельности

 

int delayTime = 4;

int delayTime3 = 3000;


void setup() {
 
  pinMode(ledPin, OUTPUT);    

  pinMode(ledPin2, OUTPUT);   
 
 
}

void loop(){

   digitalWrite(ledPin, LOW); 
    delayMicroseconds(delayTime3); 

      digitalWrite(ledPin2, LOW); 
  
 
      delay(delayTime);
     digitalWrite(ledPin, HIGH); 
     delayMicroseconds(delayTime3) ;

        digitalWrite(ledPin2, HIGH); 
    
       delay(delayTime);

 

 digitalWrite(ledPin2, LOW); 
    delayMicroseconds(delayTime3); 

      digitalWrite(ledPin, LOW); 
  
 
      delay(delayTime);
     digitalWrite(ledPin2, HIGH); 
     delayMicroseconds(delayTime3) ;

        digitalWrite(ledPin, HIGH); 
    
       delay(delayTime);

 

Так вроде всё красиво и как нужно работает

Но когда пишу код чтобы он у меня в схеме работал сигнал получается корявыё при включении

 

 


const int buttonPin2 = 11; 

const int buttonPin = 12;    
const int ledPin =  8;     

const int ledPin2 =  9;  

int buttonState = 0;     

int buttonState2 = 0;  

int delayTime = 4;

int delayTime3 = 3000;


void setup() {
 
  pinMode(ledPin, OUTPUT);    

  pinMode(ledPin2, OUTPUT);   
 
  pinMode(buttonPin, INPUT); 
pinMode(buttonPin2, INPUT);    
}

void loop(){

  buttonState = digitalRead(buttonPin);
    buttonState2 = digitalRead(buttonPin2);
  

  
 
  if (buttonState == HIGH) {      //   Мотор крутится в перёд  +Pin 12
   
    digitalWrite(ledPin, LOW);   // Эмуляция сигнала вместо опти.  Датчика
    delayMicroseconds(delayTime3); 

      digitalWrite(ledPin2, LOW); 
  
 
      delay(delayTime);
     digitalWrite(ledPin, HIGH); 
     delayMicroseconds(delayTime3) ;

        digitalWrite(ledPin2, HIGH); 
    
       delay(delayTime);
       
      
  }
  else {
   
    digitalWrite(ledPin, LOW);
     digitalWrite(ledPin2, LOW);
    
  }

    
     if (buttonState2 == HIGH) {    //Мотор крутится  назад   +Pin 11  
  
        digitalWrite(ledPin2, LOW); //Эмуляция сигнала вместо опти.  Датчика
    delayMicroseconds(delayTime3); 

      digitalWrite(ledPin, LOW); 
  
 
      delay(delayTime);
     digitalWrite(ledPin2, HIGH); 
     delayMicroseconds(delayTime3) ;

        digitalWrite(ledPin, HIGH); 
    
       delay(delayTime);
      
    
  }
  else {
   
    digitalWrite(ledPin2, LOW);
     digitalWrite(ledPin, LOW);
  
  }
}

 

Подскажите пожалуйста как это можно исправить?

Чтобы импульсы шли ровна как в первой 1-2 осциллограмме коде?

RANDREY
Offline
Зарегистрирован: 10.06.2012

а на микросхеме не реально сделать? TTL уровни

bit
Offline
Зарегистрирован: 07.05.2012

Дак я когда  по отдельности код пишу у меня сигнал нормальный идёт а когда делаю кнопки вперёд назад запуска у меня сигнал кривой получается

bit
Offline
Зарегистрирован: 07.05.2012

Поправте код пожалуйста

 

Snubist
Offline
Зарегистрирован: 18.02.2013

Хз, вроде все правильно. Попробуй у кнопкок дребезг убрать.

bit
Offline
Зарегистрирован: 07.05.2012

Дак я просто перемычку ставлю без кнопки и такая же ерунда

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

поставьте Т-триггер, и сразу будет готовый сигнал :)

Snubist
Offline
Зарегистрирован: 18.02.2013

А так?

const int buttonPin2 = 11; 

const int buttonPin = 12;    
const int ledPin =  8;     

const int ledPin2 =  9;  

int buttonState = 0;     

int buttonState2 = 0;  

int delayTime = 4;

int delayTime3 = 3000;
int OldButon=0;
int OldButon2=0;

void setup() {
 
  pinMode(ledPin, OUTPUT);    

  pinMode(ledPin2, OUTPUT);   
 
  pinMode(buttonPin, INPUT); 
pinMode(buttonPin2, INPUT);    
}

void loop(){

  buttonState = digitalRead(buttonPin);
    buttonState2 = digitalRead(buttonPin2);
if (buttonState == HIGH && OldButon==LOW){
  delay (300);
}  
if (buttonState2 == HIGH && OldButon2==LOW){
  delay (300);
} 
  OldButon=buttonState;
  OldButon=buttonState2;  
 
  if (buttonState == HIGH) {      //   Мотор крутится в перёд  +Pin 12
   
    digitalWrite(ledPin, LOW);   // Эмуляция сигнала вместо опти.  Датчика
    delayMicroseconds(delayTime3); 

      digitalWrite(ledPin2, LOW); 
  
 
      delay(delayTime);
     digitalWrite(ledPin, HIGH); 
     delayMicroseconds(delayTime3) ;

        digitalWrite(ledPin2, HIGH); 
    
       delay(delayTime);
       
      
  }
  else {
   
    digitalWrite(ledPin, LOW);
    delayMicroseconds(delayTime3); 
     digitalWrite(ledPin2, LOW);
    
  }

    
     if (buttonState2 == HIGH) {    //Мотор крутится  назад   +Pin 11  
  
        digitalWrite(ledPin2, LOW); //Эмуляция сигнала вместо опти.  Датчика
    delayMicroseconds(delayTime3); 

      digitalWrite(ledPin, LOW); 
  
 
      delay(delayTime);
     digitalWrite(ledPin2, HIGH); 
     delayMicroseconds(delayTime3) ;

        digitalWrite(ledPin, HIGH); 
    
       delay(delayTime);
      
    
  }
  else {
   
    digitalWrite(ledPin2, LOW);
    delayMicroseconds(delayTime3); 
     digitalWrite(ledPin, LOW);
  
  }
}

 

bit
Offline
Зарегистрирован: 07.05.2012

А так вообще белиберда

bit
Offline
Зарегистрирован: 07.05.2012

Вот блин убрал из кода эти строки и всё заработало нормально , сигнал стал ровный

}
  else {
   
    digitalWrite(ledPin2, LOW);
     digitalWrite(ledPin, LOW);
  

 

Snubist
Offline
Зарегистрирован: 18.02.2013

Ну значит делай нормальные кнопки, с защитой от дребезга.

bit
Offline
Зарегистрирован: 07.05.2012

Привет всем .

Подскажите пожалуйста как можно сделать при подачи на аналоговый вход так что  бы скажем при 500 – 510 значении делалось одно действие .

А при 530 – 540 значение делалась другое действие

 

int sensePin =0;
int ledPin =9;

void setup(){
  analogReference(DEFAULT);
  pinMode(ledPin, OUTPUT);
}

void loop(){
  int val = analogRead(sensePin);
  
  if(val < 800) digitalWrite(ledPin, HIGH);
  else digitalWrite(ledPin, LOW);
}

 

Evgen
Evgen аватар
Offline
Зарегистрирован: 10.06.2011

Например так

int x;
void setup()
{
  analogReference(DEFAULT);
}
void loop()
{
  x=analogRead(0);
  if((x>499)&&(x<511)) // если х больше 499 и меньше 511
  {
    // делаем одно
  }
  f((x>529)&&(x<541)) // если х больше 529 и меньше 541
  {
    // делаем другое
  }
}

 

bit
Offline
Зарегистрирован: 07.05.2012

Спасибо сейчас попробую

bit
Offline
Зарегистрирован: 07.05.2012

 

Заработало))))

Fantick
Offline
Зарегистрирован: 09.12.2011

Добрый день!

Есть такая проблема, со счетчика электроэнернии приходит импульс, но прерывание происходит 3-4 раза за один импульс, подскажите пожалуйста,  как этого избежать, желательно не аппаратно.

//Number of pulses, used to measure energy.
long pulseCount = 0;   

//Used to measure power.
unsigned long pulseTime,lastTime;

//power and energy
double power, elapsedkWh;

//Number of pulses per wh - found or set on the meter.
int ppwh = 1; //1000 pulses/kwh = 1 pulse per wh

void setup()
{
Serial.begin(115200);

// KWH interrupt attached to IRQ 1 = pin3
attachInterrupt(1, onPulse, FALLING);
}


void loop()
{

}

// The interrupt routine
void onPulse()
{

//used to measure time between pulses.
lastTime = pulseTime;
pulseTime = micros();

//pulseCounter
pulseCount++;

//Calculate power
power = (3600000000.0 / (pulseTime - lastTime))/ppwh;

//Find kwh elapsed
elapsedkWh = (1.0*pulseCount/(ppwh*1000)); //multiply by 1000 to pulses per wh to kwh convert wh to kwh

//Print the values.
Serial.print(power,4);
Serial.print(" ");
Serial.println(elapsedkWh,3);
}

 

Платформа: Ардуина мега.

Пин: ПИН подтянут к земле.

Длина импульса 80мс.

На осцилограмме все чисто, дребезга не наблюдается.

 

tmr
Offline
Зарегистрирован: 19.05.2014
Fantick, если это весь листинг программы и нет каких-то других причин, я бы посоветовал не использовать прерывание вообще, а определять импульс вручную в главном цикле. Если так нельзя, то необходимо хотя-бы вынести тяжелые операции из обработчика прерывания. Кроме того, об этом сказано в документации на attachInterrupt, таймеры и связанные с ними операции могут работать некорректно внутри прерывания, т.е. это micros() и Serial, а само прерывание должно быть максимально быстрым.
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

То есть кондёр нан на 10 - это уже крутое аппаратное решение?

Fantick
Offline
Зарегистрирован: 09.12.2011

Это не весь листинг, там будут задействованы 4 прерывания, и отправка данных на xively через gprs модем, и чтоб при отправке ничего не потерялось, хотел использовать прерывания, насчет тяжелых операций я учту это замечание, насчет аппаратного избавления от дребезга боюсь конденсаторами не обойтись, надо будет еще инв. триггеры шмитта ставить, в моем случае это неудобно, если не получится программно, понятно что придется ваять аппаратно.