Помогите пожалуйста с генератором...

andrey_ntl
Offline
Зарегистрирован: 30.01.2015

Приветствую всех! Нужна Ваша помощь, так как я в программировании совсем слаб. Есть плата Arduino Nano (Atmega 328). Мне нужно на ее основе сделать генератор прямоугольных импульсов с регулируемой частотой от 1Гц до 15 Гц, амплитудой 5 В. так же желательна регулировка скважности. Кто-нибудь может помочь со схемой и кодом?!

 

 
Пробовал данный скетч, но тут ниже 16Гц получить не удается...
 
#define OUT 9          // вывод выходного сигнала
 
unsigned long frequency = 0; 
 
void setup()
{
Serial.begin(9600);
pinMode(OUT, OUTPUT);
Serial.println("START");
}
 
void loop()
{
  if(Serial.available()) Set_frequency(Serial.parseInt());
 
}
 
void Set_frequency(uint32_t freq)
{
 uint16_t ocr;
 cli();
 if(freq)
  {
   TCCR1A = 0b01000000;
   if(freq < 134)
    {
   TCCR1B = 0b00001010;
   ocr = 1000000/freq - 1;
   freq = 1000000/(ocr+1);
    }
    else
    {
      TCCR1B = 0b00001001;
      ocr = 8000000/freq - 1;
      freq = 8000000/(ocr+1);   
    }
 
    OCR1AH = highByte(ocr); 
    OCR1AL = lowByte(ocr);
    TIMSK1 = 0b00000010;
  }
  else
  {
    TCCR1A = 0;
    TCCR1B = 0;
    TIMSK1 = 0;
    freq = 0;
  }
 
  sei();
  Serial.println(freq);
}
ISR(TIMER1_COMPA_vect){
}
 
Заранее благодарю!
bwn
Offline
Зарегистрирован: 25.08.2014

Вам это надо насколько точно и с каким шагом?

void setup() {               
  // Инициализируем цифровой вход/выход в режиме выхода.
  // Выход 13 на большинстве плат Arduino подключен к светодиоду на плате.
  pinMode(13, OUTPUT);   
}
 
void loop() {
  digitalWrite(13, HIGH);   // зажигаем светодиод
  delay(500);              
  digitalWrite(13, LOW);    // выключаем светодиод
  delay(500);             
}

 

Если уж совсем просто - 1Гц.

andrey_ntl
Offline
Зарегистрирован: 30.01.2015

Спасибо, что отозвались! Мне желательно шаг в 1 Гц с точностью хотя бы 100 милиГерц.

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

http://arduino.ru/tutorials/BlinkWithoutDelay

Для повышения точности вместо millis() лучше http://arduino.ru/Reference/Micros

Управление - http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-no...

Читаем, вникаем, пробуем.

andrey_ntl
Offline
Зарегистрирован: 30.01.2015

Хорошо, если появятся вопросы, то отпишусь здесь. Спасибо!

magi
Offline
Зарегистрирован: 30.01.2015



//f -частота в герцах,  D- коэффициент заполнения % (обратная величина скваженности)
void funct1(int f,int D)
{
   int T=1000/f;
   int t1=T*D/100;
   int t2=T-t1;
   digitalWrite(13, HIGH); // зажигаем светодиод
   delay(t1);
   digitalWrite(13, LOW); // выключаем светодиод
   delay(t2);
}

Я думаю как-то так.

Ислам Урус
Offline
Зарегистрирован: 08.07.2016

Друзья, нужна ваша помощь, нужен генератор прямоугольных импульсов от 1 до 50 герц с регулируемой частотой. Помогите пожалуйста!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

и чем вы собираетесь регулировать частоту?

 

Ислам Урус
Offline
Зарегистрирован: 08.07.2016

С помощью потенциометра

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Лови. Проверил на ошибки но в палату не загружал

// программа генератор 1 до 50 герц 
/*
  генератор сигнал -> 13
            земля  -> GND
   потенциметр верхн выв -> =5в
               сред выв  -> A0
             нижний выв  -> GND              
*/
const int out_pin=13;// нога генератора
const int analogInPin = A0;// нога потенциометра
int frequency = 1; // частота от 1 до 50

void non_stop_program1(uint16_t span) {
  static uint32_t future = 0;
  static uint8_t stat = 0;  
  if (millis()<future) return ;
  future += span;
  stat =!stat;
  digitalWrite(out_pin, stat);
}
void setup() {

  pinMode(out_pin, OUTPUT);
}
void loop() {
  frequency = map(analogRead(analogInPin), 0, 1023, 1, 50);
  non_stop_program1(500/frequency);
}

 

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Ислам Урус пишет:
Друзья, нужна ваша помощь, нужен генератор прямоугольных импульсов от 1 до 50 герц с регулируемой частотой. Помогите пожалуйста!

Както делал для медленного ШИМ`а

#include <DigOut.h>//https://yadi.sk/d/NM4S6HmFrTRu6

DigOut generator(13);//выход импульсов на 13 пине

void setup(){}

void loop(){
  //тут опрашиваем потенциометр
  //заносим значение в переменную
  //подставляем вместо 1000 для регулировки периода
  //или вместо 50 для регулировки скважности
generator.lpwm(1000,50);//период 1с (1Гц) заполнение 50 %
}

 

Ислам Урус
Offline
Зарегистрирован: 08.07.2016

Ура! Получилось, 1 - 49.54 Герц. Огромное спасибо, я так благодарен вам.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Ну раз получилось, то код в студию.

dimanoid999
Offline
Зарегистрирован: 20.11.2016

Спасибо большое за библиотеку. Думал не найду ничего подходящего. А с этой библой получилось то что нужно.

/*
 
AnalogReadSerial
 
Считывает аналоговый сигнал на пине 0 и отображает результат на серийном мониторе.
 
Подключите центральный пин потенциометра к пин А0 на плате, боковые - к +5 вольтам и к земле (-).
 
*/
 
// цикл setup отрабатывает один раз после перезагрузки платы Arduino
#include <DigOut.h>//загрузка библиотеки есть на  <a href="https://yadi.sk/d/NM4S6HmFrTRu6"
 
DigOut generator(13);//выход импульсов на 13 пине
void setup() {
 
// инициализация обмена данными по серийному протоколу со скоростью 9600 бит в секунду:
 
Serial.begin(9600);
 
}
 
// цикл loop повторяется бесконечно:
 
void loop() {
 
// считывает значение с аналогового пина 0 и 1:
 
int FrequencyValue = analogRead(A0);
int SquaValue = analogRead(A1)/10;
 
// отображает считанное значение:
 
Serial.println(FrequencyValue);
Serial.println(SquaValue);
delay(1); // задержка между считываниями для стабильности работы
generator.lpwm(FrequencyValue,SquaValue);//период 1с (1Гц) заполнение 50 %
}
еще раз спасибо!!! Удачи!
rybakv
Offline
Зарегистрирован: 04.09.2017

добрый день. у меня есть задачка, но познания не позволяют решить её гладко. я хочю сделать управляемый инвентор, тоесть управлять мостом из 4 НПН транзисторов. частота от 50 до 150 Гц. регулировка потенциометром с шагом 1 или 2 Гц( не пренципиально). транзисторы будут в ключевом режиме. помогите пожалуйста

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

rybakv. Не уверен что у вас что-то выйдет. Но вот вам код.

//**/
unsigned long mill, micr;
//------Cl_Blinker----------------------
// класс низкочастотный генератор
class Cl_Blinker {
  protected:
    const byte pin;
    bool led;
    bool statBlink;
    unsigned int *freq;
    unsigned long past, time;
  public:
    Cl_Blinker(byte pin_, unsigned int *freq_): pin(pin_), freq(freq_) {}
    void setup() {
      pinMode(pin, OUTPUT);
      digitalWrite(pin, led = 1);
    }
    void loop() {
      if (micr - past >= time) {
        if ((*freq) > 0)time = 500000ul / (*freq);
        past = micr;
        digitalWrite(pin, led = !led);
      }
    }
};
//-------Cl_analogRead-------------------------
// регулятор потенциометром
class Cl_analogRead {
  protected:
    byte pin;
    unsigned int *val, maxim, minim;
    char *name;
    unsigned int past;
  public:
    Cl_analogRead(byte pin_, unsigned int *val_, unsigned int maxim_, unsigned int minim_, char* name_):
      pin(pin_), val(val_), maxim(maxim_), minim(minim_), name(name_) {

    }
    void setup() {}
    void loop() {
      if (mill - past >= 200) {
        past = mill;
        *val = map(analogRead(pin), 0, 1023, maxim, minim);
        Serial.println();
        Serial.print(name);
        Serial.print(*val);
      }
    }
};
//-----компоновка----------------------
unsigned int freq = 50;
Cl_Blinker Blinker(/*пин*/13,/*переменая частота Гц*/&freq);
Cl_analogRead  Rez1(/*пин*/A0,/*переменная*/&freq,/*max Гц*/150,/*min Гц*/50,/*величина*/"freq=");
//-----main-----------------------
int main() {
  init();
  // setup()
  Serial.begin(9600);
  Blinker.setup();
  Rez1.setup();
  for (;;) {
    // loop()
    mill = millis();
    micr = micros();
    Blinker.loop();
    Rez1.loop();
  }
  return 0;
}
/*Скетч использует 2528 байт (8%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 226 байт (11%) динамической памяти, оставляя 1822 байт для локальных переменных. Максимум: 2048 байт.
*/

 

rybakv
Offline
Зарегистрирован: 04.09.2017

Спасибо большое qwone! скетч заработал. менял для проверки частоту 1 -10 гц. все работает. только управлять буду двумя Полевыми транзюками и выход через трансформатор с УПСа.

для этого добавил в код

Cl_Blinker(byte pin_, unsigned int *freq_): pin(pin_), freq(freq_) {}
    void setup() {
      pinMode(pin, OUTPUT);
      pinMode(12,OUTPUT);
      digitalWrite(pin, led = 1);
      digitalWrite(12,!led);
    }
    void loop() {
      if (micr - past >= time) {
        if ((*freq) > 0)time = 500000ul / (*freq);
        past = micr;
        digitalWrite(pin, led = !led);
        digitalWrite(12, !led);
 
И вопросы:
1.нужно ли перед и после строчки digitalWrite(12, !led); поставить delayMicroseconds(время срабатывания транзистора), для коректной работы установки.
2 какую максимальную частоту можно получить из даного скетча
Еще раз спасибо
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скетч расчитан для генерации низких частот. А вот чем выше частота,тем больше будет частота плавать из-за Serial и отработки потенциометра. Можно и здесь чуть подправить, но тогда скетч приобритет сильную специфичность, непонятную вам. Даже и в этом виде скетч уже непонятен для вас. delayMicroseconds разумеется на ваше усмотрение. На низких частотах это строка может быть опущена. 

rybakv
Offline
Зарегистрирован: 04.09.2017

qwone, а низкие частоты это до 1 кГц?

Romhik
Offline
Зарегистрирован: 11.10.2017

qwone пишет:

Лови. Проверил на ошибки но в палату не загружал

// программа генератор 1 до 50 герц 
/*
  генератор сигнал -> 13
            земля  -> GND
   потенциметр верхн выв -> =5в
               сред выв  -> A0
             нижний выв  -> GND              
*/
const int out_pin=13;// нога генератора
const int analogInPin = A0;// нога потенциометра
int frequency = 1; // частота от 1 до 50

void non_stop_program1(uint16_t span) {
  static uint32_t future = 0;
  static uint8_t stat = 0;  
  if (millis()<future) return ;
  future += span;
  stat =!stat;
  digitalWrite(out_pin, stat);
}
void setup() {

  pinMode(out_pin, OUTPUT);
}
void loop() {
  frequency = map(analogRead(analogInPin), 0, 1023, 1, 50);
  non_stop_program1(500/frequency);
}

Я проверил, у меня отлично работает!

А как сделать больше частоту, например от 1 до 1000гц?