biele01
23.03.2010, 08:26
Hallo bastler.
Ich habe ein kleines problem mit meinem Arduino 2009 Board. Das Arduino hat von haus aus 6 PWM Ports zur verfügung. 2 davon können als HighPWM Port genutzt werden, indem ich ihre taktung intern durch gesetzte Register erhöhe. dazu habe ich einen timer der jede s bis 65535 zählt(allerdingds ist der timer irgendwie mit der frequenz des PWMPortes verknüpft)keine ahnung..... erreicht mein timer die hälfte der zu zählenden werte, setzt er den PWM Dutycycle auf 100% als 255. Sonst is er 0. Das heißt ich habe jetzt einen Pulse von 1Hz- die Frequenz kann ich mit einer varriablen regeln (mein eingelesener wert werte von 0 - 15000) indem ich nach jedemmal zählen den aktuell gemessenen wert dem counter dazu addiere. also eine geregelte Frequenz.
Jetzt funktioniert das hervorragend mit einer LED und Einen PiezzoLautsprecher. aber ich brauche das ganze um eine Schrittmotorensteuerung zu befeuern. (also ein Flankenwechsel von 3,4-5V zu <0,8V löst ein schritt aus.) und das ergebniss ist das mein Motor total verrückt spielt als würde er unzählige verschiedene impulse bekommen. Daraus schließe ich das das 100% dutycycle nicht aus einem Durchgängigen signal besteht sondern aus 65535 kleinen Flankenwechseln.???kann das sein?
habe einen kleinen Kondensator mal zwischen meinen Impulsausgang und SM Steuerung geklemmt, und siehe da das Flattern und summen ist fast weg aber komisch verhalten tut sich der Motor trotzdem noch. zb macht keine ichtigen Microschritte wie er soll. der code sieht etwa so aus...
void writetakt( uint8_t val ) {
OCR1A = (val);
}
uint16_t phase = 0;
uint16_t speed = 0;
uint8_t sample = 0;
SIGNAL(TIMER1_OVF_vect){
writetakt(sample);
phase += speed;
if(phase >= 32768)
sample = 0;
else
sample = 255;
if (frequenzkurve < 1 )
sample = 255;
}
wobei frequenzkurve mein eingelesener drehregler ist.
completter Code ist:
unsigned int frequenzkurve = 0;
void writetakt( uint8_t val ) {
OCR1A = (val);
}
uint16_t phase = 0;
uint16_t speed = 0;
uint8_t sample = 0;
SIGNAL(TIMER1_OVF_vect){
writetakt(sample);
phase += speed;
if(phase >= 32768)
sample = 0;
else
sample = 255;
if (frequenzkurve < 1 )
sample = 255;
}
////////////////////////////////////////////////////////////////////////////////////////////
unsigned int frequenzkurve_out = 0;
unsigned int frequenzkurve_B = 0;
unsigned int frequenzkurve_C = 0;
unsigned int frequenzkurve_D = 0;
unsigned int frequenzkurve_E = 0;
unsigned int frequenzkurve_F = 0;
/////////////////////////// IN und OUTPUT pins vergeben ///////////////////////////////////
int i=0;
int taktPin = 9; //Frequenz ausgang
int RCPin = 2; //PWM eingang
int Motor_drehrichtung = 13; // Richtungs Ausgang High = Linksrum Low = Rechtsrum
////////////////////////// zum einlesen des RC Signals //////////////////////////////////////
int timeX = 250;
int timeX_old = 250;
int timeX_old_B = 250;
int timeX_old_C = 250;
int timeX_fehler = 250;
int Toleranz_PWM = 20;
int timeX_final = 250;
int timeX_final_old = 250;
int timeX_final_old_B = 250;
int timeX_final_old_C = 250;
int timeX_final_old_D = 250;
int timeX_final_old_E = 250;
int timeX_final_old_F = 250;
float timeX_final_negativ = 250;
float timeX_halb = 250;
long lastPulseX = 0; // die Zeit in Millisecunden des letzten Pulses
long mstime = 0; // Liest die zeit in Millisecunden
long hptime = 0;
extern volatile unsigned long timer0_overflow_count;
unsigned long hpticks (void)
{
return (timer0_overflow_count << 8) + TCNT0;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200); // Kommunikationsgeschwindigkeit Pc
pinMode (taktPin, OUTPUT);
pinMode(RCPin, INPUT); //R/C Pin als Input setzten
pinMode(Motor_drehrichtung, OUTPUT); //LED simuliet Rückwärtslauf (pin High versteht Schrittmotorsteuerung als RW)
TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(CS10) | _BV(WGM12);
TIMSK1 |= _BV(TOIE1);
}
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
void loop() {
//////////////////////////////////// RC einlesen erster Durchlauf (timeX_0ld)/////////////////////////////////////////
if(millis() - lastPulseX >= 5)
{ while(!digitalRead(RCPin) == HIGH) //Auf das Nächste RC Signal von RCPin Warten
{continue;}
mstime = millis();
hptime = hpticks(); //wenn das Signal Ankommt, Beginn der Startzeit aufzeichnun
while(!digitalRead(RCPin) == LOW)
{continue;}
mstime = millis();
timeX = (hpticks()) - hptime - 220; //Hier wird der unterschied zwischen start und endzeit ermittelt, Das Ergebnis ist das Rc Signal.
hptime = 0;
lastPulseX = millis();
}
///////////////////////////////////////////////////////////////////////////////////////////////
if (timeX > (timeX_old_C + Toleranz_PWM))
{
Serial.println("-ABGEFANGEN---");
Serial.println( timeX );
timeX_fehler = timeX ;
timeX = (0.2*timeX_old)+(0.3*timeX_old_B)+(0.5*timeX_old_C );
Serial.println("X");
Serial.println("-ANGEGLICHEN----");
Serial.println( timeX);
Serial.println("----------------------------");
if ( timeX == timeX_old_C)
{timeX =timeX_fehler;}
}
if (timeX < (timeX_old_C - Toleranz_PWM))
{
Serial.println("-ABGEFANGEN---");
Serial.println( timeX);
timeX_fehler = timeX ;
timeX = (0.2*timeX_old)+(0.3*timeX_old_B)+(0.5*timeX_old_C );
Serial.println("X");
Serial.println("-ANGEGLICHEN----");
Serial.println( timeX);
Serial.println("----------------------------");
if ( timeX == timeX_old_C)
{timeX =timeX_fehler;}
}
/////////////////////////////////////////////////////////////////
timeX_final = (timeX * 0.05) + (timeX_final_old * 0.05) + (timeX_final_old_B * 0.10)+
(timeX_final_old_C * 0.10)+ (timeX_final_old_D * 0.15) + (timeX_final_old_D * 0.20) + (timeX_final_old_D * 0.35);
if (timeX_final > 500)
{timeX_final = 500;}
if (timeX_final < 0)
{timeX_final = 0;}
if (timeX_final < 245)
{
timeX_final_negativ = timeX_final-(timeX_final * 2)+255;
frequenzkurve = ((timeX_final_negativ) * (timeX_final_negativ)*(0.1*timeX_final_negativ)/108);
digitalWrite (Motor_drehrichtung,HIGH);
}
if (timeX_final >= 250)
{
timeX_halb = timeX_final - 245;
frequenzkurve = ((timeX_halb) * (timeX_halb)* (0.1*timeX_halb)/91);
digitalWrite (Motor_drehrichtung,LOW);
}
frequenzkurve_out = (frequenzkurve * 0.05) + (frequenzkurve_B * 0.10) + (frequenzkurve_C * 0.15)+
(frequenzkurve_D * 0.20)+ (frequenzkurve_E * 0.20) + (frequenzkurve_F * 0.30);
timeX_old_C = timeX_old_B;
timeX_old_B = timeX_old;
timeX_old = timeX;
timeX_final_old_F = timeX_final_old_E;
timeX_final_old_E = timeX_final_old_D;
timeX_final_old_D = timeX_final_old_C;
timeX_final_old_C = timeX_final_old_B;
timeX_final_old_B = timeX_final_old;
timeX_final_old = timeX_final;
frequenzkurve_F = frequenzkurve_E;
frequenzkurve_E = frequenzkurve_D;
frequenzkurve_D = frequenzkurve_C;
frequenzkurve_C = frequenzkurve_B;
frequenzkurve_B = frequenzkurve;
speed = frequenzkurve_out;
/////////////////////////////////////////////////////////////////////////////////////////
/* Serial.print(timeX);
Serial.print("-------");
Serial.print(timeX_final);
Serial.print("-------");
Serial.println(frequenzkurve_out);
*/
}
also ich lese hier ein RC Signal ein(pin 2), glätte es in mehreren Stufen(0,1* erster wet+0,9*zweiterwert), filter ungewünschte fehlmessungen raus, erzeuge den counter und gebe eine frequenz aus(pin 9), und ein richtungssignal( auf pin 13).is etwas chaotisch.
Wie kann ich ein sauberes Rechtecksignal bekommen, oder es zumindest so glätten das ich 15kHz noch ausgeben kann aber alle frequenzen die weit darüber liegen geglättet werden.---Kondensator aber welchen?)
Ich habe ein kleines problem mit meinem Arduino 2009 Board. Das Arduino hat von haus aus 6 PWM Ports zur verfügung. 2 davon können als HighPWM Port genutzt werden, indem ich ihre taktung intern durch gesetzte Register erhöhe. dazu habe ich einen timer der jede s bis 65535 zählt(allerdingds ist der timer irgendwie mit der frequenz des PWMPortes verknüpft)keine ahnung..... erreicht mein timer die hälfte der zu zählenden werte, setzt er den PWM Dutycycle auf 100% als 255. Sonst is er 0. Das heißt ich habe jetzt einen Pulse von 1Hz- die Frequenz kann ich mit einer varriablen regeln (mein eingelesener wert werte von 0 - 15000) indem ich nach jedemmal zählen den aktuell gemessenen wert dem counter dazu addiere. also eine geregelte Frequenz.
Jetzt funktioniert das hervorragend mit einer LED und Einen PiezzoLautsprecher. aber ich brauche das ganze um eine Schrittmotorensteuerung zu befeuern. (also ein Flankenwechsel von 3,4-5V zu <0,8V löst ein schritt aus.) und das ergebniss ist das mein Motor total verrückt spielt als würde er unzählige verschiedene impulse bekommen. Daraus schließe ich das das 100% dutycycle nicht aus einem Durchgängigen signal besteht sondern aus 65535 kleinen Flankenwechseln.???kann das sein?
habe einen kleinen Kondensator mal zwischen meinen Impulsausgang und SM Steuerung geklemmt, und siehe da das Flattern und summen ist fast weg aber komisch verhalten tut sich der Motor trotzdem noch. zb macht keine ichtigen Microschritte wie er soll. der code sieht etwa so aus...
void writetakt( uint8_t val ) {
OCR1A = (val);
}
uint16_t phase = 0;
uint16_t speed = 0;
uint8_t sample = 0;
SIGNAL(TIMER1_OVF_vect){
writetakt(sample);
phase += speed;
if(phase >= 32768)
sample = 0;
else
sample = 255;
if (frequenzkurve < 1 )
sample = 255;
}
wobei frequenzkurve mein eingelesener drehregler ist.
completter Code ist:
unsigned int frequenzkurve = 0;
void writetakt( uint8_t val ) {
OCR1A = (val);
}
uint16_t phase = 0;
uint16_t speed = 0;
uint8_t sample = 0;
SIGNAL(TIMER1_OVF_vect){
writetakt(sample);
phase += speed;
if(phase >= 32768)
sample = 0;
else
sample = 255;
if (frequenzkurve < 1 )
sample = 255;
}
////////////////////////////////////////////////////////////////////////////////////////////
unsigned int frequenzkurve_out = 0;
unsigned int frequenzkurve_B = 0;
unsigned int frequenzkurve_C = 0;
unsigned int frequenzkurve_D = 0;
unsigned int frequenzkurve_E = 0;
unsigned int frequenzkurve_F = 0;
/////////////////////////// IN und OUTPUT pins vergeben ///////////////////////////////////
int i=0;
int taktPin = 9; //Frequenz ausgang
int RCPin = 2; //PWM eingang
int Motor_drehrichtung = 13; // Richtungs Ausgang High = Linksrum Low = Rechtsrum
////////////////////////// zum einlesen des RC Signals //////////////////////////////////////
int timeX = 250;
int timeX_old = 250;
int timeX_old_B = 250;
int timeX_old_C = 250;
int timeX_fehler = 250;
int Toleranz_PWM = 20;
int timeX_final = 250;
int timeX_final_old = 250;
int timeX_final_old_B = 250;
int timeX_final_old_C = 250;
int timeX_final_old_D = 250;
int timeX_final_old_E = 250;
int timeX_final_old_F = 250;
float timeX_final_negativ = 250;
float timeX_halb = 250;
long lastPulseX = 0; // die Zeit in Millisecunden des letzten Pulses
long mstime = 0; // Liest die zeit in Millisecunden
long hptime = 0;
extern volatile unsigned long timer0_overflow_count;
unsigned long hpticks (void)
{
return (timer0_overflow_count << 8) + TCNT0;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200); // Kommunikationsgeschwindigkeit Pc
pinMode (taktPin, OUTPUT);
pinMode(RCPin, INPUT); //R/C Pin als Input setzten
pinMode(Motor_drehrichtung, OUTPUT); //LED simuliet Rückwärtslauf (pin High versteht Schrittmotorsteuerung als RW)
TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(CS10) | _BV(WGM12);
TIMSK1 |= _BV(TOIE1);
}
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
void loop() {
//////////////////////////////////// RC einlesen erster Durchlauf (timeX_0ld)/////////////////////////////////////////
if(millis() - lastPulseX >= 5)
{ while(!digitalRead(RCPin) == HIGH) //Auf das Nächste RC Signal von RCPin Warten
{continue;}
mstime = millis();
hptime = hpticks(); //wenn das Signal Ankommt, Beginn der Startzeit aufzeichnun
while(!digitalRead(RCPin) == LOW)
{continue;}
mstime = millis();
timeX = (hpticks()) - hptime - 220; //Hier wird der unterschied zwischen start und endzeit ermittelt, Das Ergebnis ist das Rc Signal.
hptime = 0;
lastPulseX = millis();
}
///////////////////////////////////////////////////////////////////////////////////////////////
if (timeX > (timeX_old_C + Toleranz_PWM))
{
Serial.println("-ABGEFANGEN---");
Serial.println( timeX );
timeX_fehler = timeX ;
timeX = (0.2*timeX_old)+(0.3*timeX_old_B)+(0.5*timeX_old_C );
Serial.println("X");
Serial.println("-ANGEGLICHEN----");
Serial.println( timeX);
Serial.println("----------------------------");
if ( timeX == timeX_old_C)
{timeX =timeX_fehler;}
}
if (timeX < (timeX_old_C - Toleranz_PWM))
{
Serial.println("-ABGEFANGEN---");
Serial.println( timeX);
timeX_fehler = timeX ;
timeX = (0.2*timeX_old)+(0.3*timeX_old_B)+(0.5*timeX_old_C );
Serial.println("X");
Serial.println("-ANGEGLICHEN----");
Serial.println( timeX);
Serial.println("----------------------------");
if ( timeX == timeX_old_C)
{timeX =timeX_fehler;}
}
/////////////////////////////////////////////////////////////////
timeX_final = (timeX * 0.05) + (timeX_final_old * 0.05) + (timeX_final_old_B * 0.10)+
(timeX_final_old_C * 0.10)+ (timeX_final_old_D * 0.15) + (timeX_final_old_D * 0.20) + (timeX_final_old_D * 0.35);
if (timeX_final > 500)
{timeX_final = 500;}
if (timeX_final < 0)
{timeX_final = 0;}
if (timeX_final < 245)
{
timeX_final_negativ = timeX_final-(timeX_final * 2)+255;
frequenzkurve = ((timeX_final_negativ) * (timeX_final_negativ)*(0.1*timeX_final_negativ)/108);
digitalWrite (Motor_drehrichtung,HIGH);
}
if (timeX_final >= 250)
{
timeX_halb = timeX_final - 245;
frequenzkurve = ((timeX_halb) * (timeX_halb)* (0.1*timeX_halb)/91);
digitalWrite (Motor_drehrichtung,LOW);
}
frequenzkurve_out = (frequenzkurve * 0.05) + (frequenzkurve_B * 0.10) + (frequenzkurve_C * 0.15)+
(frequenzkurve_D * 0.20)+ (frequenzkurve_E * 0.20) + (frequenzkurve_F * 0.30);
timeX_old_C = timeX_old_B;
timeX_old_B = timeX_old;
timeX_old = timeX;
timeX_final_old_F = timeX_final_old_E;
timeX_final_old_E = timeX_final_old_D;
timeX_final_old_D = timeX_final_old_C;
timeX_final_old_C = timeX_final_old_B;
timeX_final_old_B = timeX_final_old;
timeX_final_old = timeX_final;
frequenzkurve_F = frequenzkurve_E;
frequenzkurve_E = frequenzkurve_D;
frequenzkurve_D = frequenzkurve_C;
frequenzkurve_C = frequenzkurve_B;
frequenzkurve_B = frequenzkurve;
speed = frequenzkurve_out;
/////////////////////////////////////////////////////////////////////////////////////////
/* Serial.print(timeX);
Serial.print("-------");
Serial.print(timeX_final);
Serial.print("-------");
Serial.println(frequenzkurve_out);
*/
}
also ich lese hier ein RC Signal ein(pin 2), glätte es in mehreren Stufen(0,1* erster wet+0,9*zweiterwert), filter ungewünschte fehlmessungen raus, erzeuge den counter und gebe eine frequenz aus(pin 9), und ein richtungssignal( auf pin 13).is etwas chaotisch.
Wie kann ich ein sauberes Rechtecksignal bekommen, oder es zumindest so glätten das ich 15kHz noch ausgeben kann aber alle frequenzen die weit darüber liegen geglättet werden.---Kondensator aber welchen?)