Potentiometer in Arduino Code implementieren

Programmierung und Hardwaredesign mit Arduino, AVR, PIC und Konsorten.

Moderatoren: MaxZ, ebastler, SeriousD

Antworten
Benutzeravatar

Thread-Ersteller
Phoenix6478
Beiträge: 582
Registriert: Do 10. Sep 2015, 11:38
Spezialgebiet: (QCW)DRSSTC, Leistungselektronik
Schule/Uni/Arbeit: FH
Hat sich bedankt: 261 Mal
Danksagung erhalten: 302 Mal
Kontaktdaten:

Potentiometer in Arduino Code implementieren

Beitrag von Phoenix6478 »

Hallo :)

Ich brauche als Signalquelle für eine Halbbrückenansteuerung einen Frequenzgenerator mit 50% Duty Cycle und variabler Frequenz. Ich habe dafür diesen Code für den Arduino UNO gefunden:

Code: Alles auswählen

//dynamic frequency generator
//for timer2
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned long frequency = 1000000 ;
void setup(){
  pinMode(9,1);
  pinMode(10,1);
  DFG(frequency);
  Serial.begin(57600);
  
}


void loop(){

}

void DFG(unsigned long tempfreq){
  cli();//disable interupts
  TCCR1A = 0;//registers for timer 1
  TCCR1B = 0;
  TCNT1=0;
  TCCR1A |= _BV(COM1A0) + _BV(COM1B0);
  TCCR1B |=_BV(WGM12); 
  TCCR1C = _BV(FOC1A);
   if(tempfreq > 122 && tempfreq < 1000001){
  OCR1A = (8000000/tempfreq)-1;//#TIMER COUNTS
  TCCR1B |= _BV(CS10);
  }
  else if(tempfreq <= 122 && tempfreq > 15){
    OCR1A = (1000000/tempfreq)-1;
    TCCR1B |= _BV(CS11);
  }
  else if(tempfreq <= 15 && tempfreq > 4){
    OCR1A = (125000/tempfreq)-1;
    TCCR1B |= _BV(CS10) + _BV(CS11);
  }
  
  //TIMSK1 = _BV(OCIE1A);//TIMER1 COMPARE INTERUPT
  sei();//enable interupts
}
Der Code stammt aus diesem Thread: https://forum.arduino.cc/index.php?topic=116094.15

Der Code macht genau dass, was ich brauche. Man kann einfach den Wert der Frequenz hinter "unsigned long frequency =" schreiben. Meine Frage lautet nun, wie ich die Frequenz mit einem Potentiometer über die AnalogIn Eingänge ändern kann? Ich habe bereits verschiedene Funktionen wie AnalogRead anstatt des Frequenzwerts versucht, aber das hat nicht funktioniert.

Was muss ich am Code ändern, dass ich mit dem Poti z.b zwischen 10 und 50kHz regeln kann?

Danke schon im Voraus

Mit besten Grüßen
Phoenix
Benutzeravatar

VDX
Beiträge: 1805
Registriert: Fr 13. Jul 2018, 18:23
Spezialgebiet: Laser und Mikro-/Nanotechnik
Hat sich bedankt: 8 Mal
Danksagung erhalten: 195 Mal

Re: Potentiometer in Arduino Code implementieren

Beitrag von VDX »

Hi Phoenix,

mit analogRead() liest du eine Spannung von 0-5V als Zahlenwert 0-1023 ein - du rechnest dann die Zahl in deinen gewünschten Wert um oder läßt es die Library machen ... mit z.B.
value = analogRead(A0);

if(value<0) value = 0;
if(value>1023) value = 1023;

pulse_us = map(value,0,1023,1,300);


-- wandle ich eine 0-5V-Spannung an einem Poti in eine "Puls-Zeit" von 1us bis 300us um ...

Viktor
Aufruf zum Projekt "Müll-freie Meere" - https://reprap.org/forum/list.php?426 -- Facebook-Gruppe - https://www.facebook.com/groups/383822522290730
Call for the project "garbage-free seas" - https://reprap.org/forum/list.php?425
Benutzeravatar

Thread-Ersteller
Phoenix6478
Beiträge: 582
Registriert: Do 10. Sep 2015, 11:38
Spezialgebiet: (QCW)DRSSTC, Leistungselektronik
Schule/Uni/Arbeit: FH
Hat sich bedankt: 261 Mal
Danksagung erhalten: 302 Mal
Kontaktdaten:

Re: Potentiometer in Arduino Code implementieren

Beitrag von Phoenix6478 »

Hallo VDX

Vielen Dank für deine Hilfe :)

Leider bin ich ein absoluter Anfänger im Bereich der Mikrocontroller :oops: . In einem anderen Forum wurde mir diese map Funktion bereits vorgeschlagen, aber ich komme einfach nicht hin.

Vorher muss ich bei Void Setup noch den Pin als Input Pin definieren, oder?

Wenn ich das Ganze mit value einfüge, kommt immer value was not declared in this scope.

Kannst du mit bitte zeigen, wie genau ich diese Funktion in diesen Code einbauen muss, damit es funktioniert?

Edit: Ich habe jetzt mal ein wenig rumprobiert, die Frequenz ändert sich mit dem Poti, aber der Output am Oszi sieht extrem unstabil aus und die Frequenz ändert sich sprungweise:

Code: Alles auswählen

//dynamic frequency generator
//for timer2
#include <avr/io.h>
#include <avr/interrupt.h>

void setup(){
  pinMode(9,1);
  pinMode(10,1);
  Serial.begin(57600);

  
}


void loop() {
  Serial.println(analogRead(A0));
  int val = analogRead(A0);
  val = map(val, 0, 1023, 1000, 50000);
  analogWrite(9, val);
    DFG(val);

}

void DFG(unsigned long tempfreq){
  cli();//disable interupts
  TCCR1A = 0;//registers for timer 1
  TCCR1B = 0;
  TCNT1=0;
  TCCR1A |= _BV(COM1A0) + _BV(COM1B0);
  TCCR1B |=_BV(WGM12); 
  TCCR1C = _BV(FOC1A);
   if(tempfreq > 122 && tempfreq < 1000001){
  OCR1A = (8000000/tempfreq)-1;//#TIMER COUNTS
  TCCR1B |= _BV(CS10);
  }
  else if(tempfreq <= 122 && tempfreq > 15){
    OCR1A = (1000000/tempfreq)-1;
    TCCR1B |= _BV(CS11);
  }
  else if(tempfreq <= 15 && tempfreq > 4){
    OCR1A = (125000/tempfreq)-1;
    TCCR1B |= _BV(CS10) + _BV(CS11);
  }
  
  //TIMSK1 = _BV(OCIE1A);//TIMER1 COMPARE INTERUPT
  sei();//enable interupts
}
Grüße
Phoenix
Benutzeravatar

Heisath
Beiträge: 539
Registriert: Mi 26. Jun 2013, 15:44
Hat sich bedankt: 33 Mal
Danksagung erhalten: 81 Mal
Kontaktdaten:

Re: Potentiometer in Arduino Code implementieren

Beitrag von Heisath »

Hi,

Du könntest an mehreren Stellen deinen Code verbessern, das müsste dann helfen. Hauptsächlich solltest du vermutlich analogRead nicht so oft machen.
Habe mal ein wenig angepasst und Kommentare entsprechend gemacht.

Teste das mal.

Code: Alles auswählen

//dynamic frequency generator
//for timer2
#include <avr/io.h>
#include <avr/interrupt.h>

void setup(){
  //setup pin modes, use constants for readability
  pinMode(A0, INPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  Serial.begin(57600);
  
}


int current_value;

void loop() {
	
	int val = analogRead(A0); // only read this once
	
	if (val != current_value) { // only do something if the value change in between reads
		current_value = val;
	
		Serial.println(current_value); // printing takes up some time, omit this if not neccessary
	
		unsigned long freq = map(current_value, 0, 1023, 1000, 50000);
		// analogWrite(9, val); // why this? This is for using PWM output -> not neccessary as you use timers directly
		DFG(freq);
	}
	
	delay(10); // only rerun the loop every 10msec
}

void DFG(unsigned long tempfreq){
	cli();//disable interupts
	TCCR1A = 0;//registers for timer 1
	TCCR1B = 0;
	TCNT1=0;
	TCCR1A |= _BV(COM1A0) + _BV(COM1B0);
	TCCR1B |=_BV(WGM12); 
	TCCR1C = _BV(FOC1A);
	if(tempfreq > 122 && tempfreq < 1000001){
		OCR1A = (8000000/tempfreq)-1;//#TIMER COUNTS
		TCCR1B |= _BV(CS10);
	}
	else if(tempfreq <= 122 && tempfreq > 15){
		OCR1A = (1000000/tempfreq)-1;
		TCCR1B |= _BV(CS11);
	}
	else if(tempfreq <= 15 && tempfreq > 4){
		OCR1A = (125000/tempfreq)-1;
		TCCR1B |= _BV(CS10) + _BV(CS11);
	}
  
  //TIMSK1 = _BV(OCIE1A);//TIMER1 COMPARE INTERUPT
  sei();//enable interupts
}
lg,
count-doku
Benutzeravatar

Thread-Ersteller
Phoenix6478
Beiträge: 582
Registriert: Do 10. Sep 2015, 11:38
Spezialgebiet: (QCW)DRSSTC, Leistungselektronik
Schule/Uni/Arbeit: FH
Hat sich bedankt: 261 Mal
Danksagung erhalten: 302 Mal
Kontaktdaten:

Re: Potentiometer in Arduino Code implementieren

Beitrag von Phoenix6478 »

Vielen Dank für Deine Hilfe und die Kommentare, Count-Doku :awesome:

Ich hab es vorher gerade übrigens auch geschafft, den Code stabiler zu bekommen, indem ich einen millis() Timer eingebaut habe. Allerdings war es trotzdem nicht so stabil, wie Deine Version.

Ich habe jetzt noch den Delay auf 100ms gestellt, jetzt gibt es absolut keine Glitches mehr.

Vielen Dank nochmal :)

Mit herzlichen Grüßen
Phoenix
Benutzeravatar

Heisath
Beiträge: 539
Registriert: Mi 26. Jun 2013, 15:44
Hat sich bedankt: 33 Mal
Danksagung erhalten: 81 Mal
Kontaktdaten:

Re: Potentiometer in Arduino Code implementieren

Beitrag von Heisath »

Schön das es funktioniert. Habe es auch gerade mal auf einem Atmel32u4 getestet und noch ein wenig verbessert.
Ich mache die Registerinits jetzt nurnoch einmalig und ändere dann nur den OCR1A Wert. Damit sind dann zwar nurnoch Frequenzen von 122Hz - 1MHz möglich, reicht aber für deinen Usecase.
Außerdem würde ich dir empfehlen einen kleinen Kondensator zwischen A0 und GND zu machen, das verhindert, dass der Wert flimmert.

Code: Alles auswählen

/*
    Name:       phtest.ino
    Created:	23.03.2019 21:03:07
    Author:     Jannis-PC\Jannis
*/

//dynamic frequency generator
//for timer2
#include <avr/io.h>
#include <avr/interrupt.h>

void setup() {
	//setup pin modes, use constants for readability
	pinMode(A0, INPUT);
	pinMode(9, OUTPUT);
	pinMode(10, OUTPUT);
	Serial.begin(57600);
	initDFG();
}


int current_value;

void loop() {

	int val = analogRead(A0); // only read this once

	if (val != current_value) { // only do something if the value change in between reads
		current_value = val;

		Serial.println(current_value); // printing takes up some time, omit this if not neccessary

		unsigned long freq = map(current_value, 0, 1023, 1000, 50000);
		// analogWrite(9, val); // why this? This is for using PWM output -> not neccessary as you use timers directly
		DFG(freq);
	}

	delay(10); // only rerun the loop every 10msec
}
void initDFG() {
	cli();//disable interupts
	TCCR1A = 0;//registers for timer 1
	TCCR1B = 0;
	TCNT1 = 0;
	TCCR1A |= _BV(COM1A0) + _BV(COM1B0);
	TCCR1B |= _BV(WGM12);
	TCCR1C = _BV(FOC1A);
	
	OCR1A = (8000000 / 50000) - 1;//#TIMER COUNTS
	TCCR1B |= _BV(CS10);
	
	//TIMSK1 = _BV(OCIE1A);//TIMER1 COMPARE INTERUPT
	sei();//enable interupts
}
void DFG(unsigned long tempfreq) {
	// only allow frequencies between 123 Hz and 1Mhz
	if (tempfreq < 123 || tempfreq > 1000000) return;

	cli();//disable interupts
	OCR1A = (8000000 / tempfreq) - 1;//#TIMER COUNTS
	//TIMSK1 = _BV(OCIE1A);//TIMER1 COMPARE INTERUPT
	sei();//enable interupts
}
Benutzeravatar

Thread-Ersteller
Phoenix6478
Beiträge: 582
Registriert: Do 10. Sep 2015, 11:38
Spezialgebiet: (QCW)DRSSTC, Leistungselektronik
Schule/Uni/Arbeit: FH
Hat sich bedankt: 261 Mal
Danksagung erhalten: 302 Mal
Kontaktdaten:

Re: Potentiometer in Arduino Code implementieren

Beitrag von Phoenix6478 »

Danke für die weitere Verbesserung, jetzt läuft es noch stabiler. Du hast recht, mit dem Kondensator flimmert das Signal weniger, wenn ich mit dem Poti die Frequenz verändere. 122Hz-1MHz ist vollkomen ausreichend, ich brauche eigentlich nur so 20-35KHz für den Resonanzwandler.

Mit besten Grüßen
Phoenix
Antworten