Hallo, also ich habs jetzt hinbekommen, Ich hab zu meinen Programm eine Interrupt service Routine gestartet .wobei ein timer bis 655XX Zählt.
aus em ich wiederum auf pin 9 ein rechtecksignal generiere. die frequenz hängt von meinem Eingelesenen RC Signal (Xsmoth) ab.
funktioniert von 0 bis 15kHz kann ich mit meiner Fernsteuerung die frequenz regeln.
Allerdings sind dadurch 2 neue Probleme entstanden. erstes ist das vermutlich durch den timer mein eingelesenes Signal vom Rc Empfänger willkürlich ab und an Unmögliche werte einliest. da muss irgendwas mit dem timing nicht mehr stimmen.
Das zweite ist das ich beim Initialisieren des Arduino oder nach einem Reset eine Kurze schnelle frequenzfolge auf pin 9 (mein ausgang) habe, was sozusagen meinen Schrittmotor beim einschalten des arduino ungewollt 200-300 schritte machen lässt. kann man das unterbinden, oder irgendwie sagen it einem Delay das die Interrupt Routine erst nach 2 Sekundn nach initialisieren beginnt, oder das 2 sekunden meine sample (0= 0V 255=5V) auf null stehen. oder bekomme ich das damit auch nicht weg.
Code:
/////////////////////////////////initialisierungen daten timer und Interrupt////////////////////////////////
float Xsmoth_plus = (Xsmoth - 250); //final smoothstepped value
float Xsmoth;
int taktPin = 9;
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 = 255;
else
sample = 0;
if (Xsmoth < 1)
sample = 0;
}
/////////////////////////////////initialisierungen daten zum PWM einlesen////////////////////////////////
int RCPin = 2; //Eingang rc signal
int Motor_drehrichtung = 13; // LED Pin(Motor Drehrichtungssignal für SM steuerung
int timeX = 0; //Gelesener Zahlenwert des RC Signals
int timeX_old = 0; // im vorherigen Durchlauf gemessener Wert (time X)
int timeX_final = 0; // Fertiger ausgegebener Wert
int Zero_delay_timeLED = 250; // Mittelstellung des RC Steuerhebels
long lastPulseX = 0; // die Zeit in Millisecunden des letzten Pulses
long mstime = 0; // Liest die zeit in Millisecunden
long hptime = 0; // Liest die Zeit in Microsecunden
extern volatile unsigned long timer0_overflow_count;
unsigned long hpticks (void)
{
return (timer0_overflow_count << 8) + TCNT0;
}
/////////////////////////////////initialisierungen für die Nichtlineare Kurvenumsetztung der werte////////////////////////////////
#define SMOOTHSTEP( Xsmoth) (( Xsmoth) * ( Xsmoth) * (3 - 2 * ( Xsmoth)))
#define SMOOTHSTEP_plus( Xsmoth_plus) (( Xsmoth_plus) * ( Xsmoth_plus) * (3 - 2 * ( Xsmoth_plus)))
float TimeX_Min_Val_minus = 1500.0; //Input Min Value ,hier wird die zu Interpolierende Range festgelegt
float TimeX_MAX_Val_minus = 0.0; //Input Max Value, hier wird die zu Interpolierende Range festgelegt
float TimeX_Min_Val_plus = 0.0; //Input Min Value ,hier wird die zu Interpolierende Range festgelegt
float TimeX_MAX_Val_plus = 1500.0; //Input Max Value ,hier wird die zu Interpolierende Range festgelegt
float N = 250.0;
float Nplus = 250.0; //Maximaler eingangswert
float v; //smoothstep expression variable
/////////////////////////////////////
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() {
if(millis() - lastPulseX >= 5) //Signal alle 5 Millisecunden auslesen
{
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.
////////////////////////////////////////Tiefpassfilter zum glätten des gemessenen wertes///////////////////////////////////////////////
timeX_final = (0.1 * timeX) + (0.9 * timeX_old); //10 Prozent des Wertes des ersten Durchgangs, werden mit 90 Prozent des Wertes des 2. Durchganges addiert
/////////////////////////////////// Wertebereich begrenzen////////////////////////////////////////////////////////////////////////////
if (timeX_final > 500)
{timeX_final = 500;}
if (timeX_final < 0)
{timeX_final = 0;}
///////////////////////////////////////werte in CW und CCW übersetzen///////////////////////////////////////////////////////////////////
if (timeX_final < 250)
{
v = timeX_final / N; // Unterteilungen geteilt durch die nummer an schritten.
v = SMOOTHSTEP(v); // Starten der smoothstep expression on v.
Xsmoth = (TimeX_MAX_Val_minus * v) + (TimeX_Min_Val_minus * (1 - v)); // Lineare Interpolation Ausführen auf basis der zuvor gesetzten werte
digitalWrite (Motor_drehrichtung,HIGH);
}
if (timeX_final > 250)
{
v = (timeX_final - 250) / Nplus; // Unterteilungen geteilt durch die nummer an schritten.
v = SMOOTHSTEP(v); // Starten der smoothstep expression on v.
Xsmoth = ((TimeX_MAX_Val_plus * v) + (TimeX_Min_Val_plus * (1 - v))); // Lineare Interpolation Ausführen auf basis der zuvor gesetzten werte
digitalWrite (Motor_drehrichtung,LOW);
}
////////////////////////////////////////////Eingegangener wert zu nächsten Loopdurchlauf übergeben//////////////////////////////////////
timeX_old = timeX_final; // messwert für Tiefpass an nächsten Durchlauf übergeben
speed = Xsmoth; //Ausgabe Frequenz geschwindigkeit
Serial.println(Xsmoth); //Zeigt das Aktuelle errechnete Ergebniss an
///////////////////////////////////////////Werte für nächsten loopdurchlauf übergeben////////////////////////////////////////////////
hptime = 0;
lastPulseX = millis();
}
}[/list]
Lesezeichen