Генерация импульсов

Тема в разделе "Arduino & Shields", создана пользователем alexzlo, 19 ноя 2016.

  1. alexzlo

    alexzlo Нерд

    Добрре время суток. Делаю генератор импульсов. но задержки у меня сделаны на delay(). Помогите перевести на millis() а то при частоте 1Гц экран lcd тупит, да и вообще это как то не правильно.
    Использую arduino uno + lcd keypad shield, 2 потенциометра. Кнопки шилда ни как не задействованы.
    Большое спасибо за помощь
    Код (C++):
    #include <LiquidCrystal.h>
    #define inj1 7
    #define freq A2
    #define duty A1
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
    int lcd_key     = 0;
    int adc_key_in  = 0;
    #define btnRIGHT  0
    #define btnUP     1
    #define btnDOWN   2
    #define btnLEFT   3
    #define btnSELECT 4
    #define btnNONE   5
      long last_f;
      long last_d;

    int read_LCD_buttons(){
    adc_key_in = analogRead(0);      // read the value from the sensor
    // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
    // we add approx 50 to those values and check to see if we are close
    if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
    if (adc_key_in < 50)   return btnRIGHT;
    if (adc_key_in < 195)  return btnUP;
    if (adc_key_in < 380)  return btnDOWN;
    if (adc_key_in < 555)  return btnLEFT;
    if (adc_key_in < 790)  return btnSELECT;
    return btnNONE;  // when all others fail, return this...
    }

    void Draw(long frq, long dty){
      lcd.setCursor(8,0);
      lcd.print("   ");
      lcd.setCursor(8,0);
      lcd.print(frq);
      lcd.setCursor(8,1);
      lcd.print("   ");
      lcd.setCursor(8,1);
      lcd.print(dty);
    }

    void setup(){
    // пин со светодиодом — выход
    pinMode(inj1, OUTPUT);
    // пин с потенциометром - вход
    pinMode(freq, INPUT);
    pinMode(duty, INPUT);

    lcd.begin(16, 2);              // start the library
    lcd.setCursor(0,0);
    lcd.print("Freq:"); // print a simple message
    lcd.setCursor(8,0);
    lcd.print(0);
    lcd.setCursor(14,0);
    lcd.print("Hz");
    lcd.setCursor(0,1);
    lcd.print("Duty:"); // print a simple message
    lcd.setCursor(8,1);
    lcd.print(0);
    lcd.setCursor(14,1);
    lcd.print("%");
    }

    void loop(){
      long f;
      long d;

      f = analogRead(freq) / 4;
      d = analogRead(duty) / 4;

      f = ceil((f*1000)/255);
      long dut = ceil((d*100)/255);
      d = ceil((d*f)/255);

      if(last_f!=hz || last_d!=dut){
      // выдаём результат
      Draw(hz, dut);
      }


      last_f = hz;
      last_d = dut;

      digitalWrite(inj1, HIGH);
      delay(d);
      digitalWrite(inj1, LOW);
      delay(f);
    }
     
    Последнее редактирование: 20 ноя 2016
  2. AlexU

    AlexU Гуру

    Аппаратный ШИМ (PWM) решит Ваши проблемы, но нужно покопаться в документации и немного подумать.
    В документации "курить" разделы про таймеры (Timer1 и Timer2), Timer0 лучше не трогать (функция 'delay()' на него завязана).
     
  3. alexzlo

    alexzlo Нерд

    на сколько я понимаю стандартно нельзя управлять частотой, а только скважностью
     
  4. qwone

    qwone Гик

    Можно. 1 вариант tone() но он выше 16 Гц.2вариант millis(). Но частота будет немножко плавать. 3 вариант лезть в аппаратную часть. Ну тогда Учится,учится учится.
     
  5. rkit

    rkit Гуру

    digitalWrite(pin, millis() % freq < duty);
     
  6. qwone

    qwone Гик

    может так
    digitalWrite(pin, (millis() / 500)%2);// генератор 1 гц
     
  7. rkit

    rkit Гуру

    нет
     
  8. qwone

    qwone Гик

    digitalWrite(pin, millis() % 1000 < 500);// генератор 1 герц с коэффициентом заполнения 50%
     
  9. alexzlo

    alexzlo Нерд

    меня бы и плавающий результат на millis устроил бы :rolleyes:
     
  10. Luk-men

    Luk-men Нуб