2017-06-13 5 views
2

Kann mir bitte jemand mit Code helfen? Ich habe ein 24 Zähne Triggerrad. Jeder Zahn wird vom Hall-Sensor registriert und ich benötige, dass Arduino 36 Impulse des entsprechenden 24-Puls-Eingangs simuliert.Arduino C++ Berechnung Triggerpunkte

Hier ist mein Code mit DelayMicroseconds, aber ich kann DelayMicroseconds nicht verwenden, weil Arduino nicht größer als 16k Mikroverzögerung versteht.

const int hall = 2; // hall sensor 
const int ledPin = 13;  // the pin that the LED is attached to 

// Variables will change: 
int teethCounter = 0; 
int hallState = 0; 
int lasthallState = 0; 
long cycles=0; 
boolean cycle = false; 
unsigned long microsStart = 0; 
unsigned long microsStop = 0; 
unsigned long usElapsed = 0; 
unsigned long usElapsedUp = 0; 
unsigned long usInterval; 


void setup() { 
// initialize the button pin as a input: 
pinMode(hall, INPUT); 
// initialize the LED as an output: 
pinMode(ledPin, OUTPUT); 
// initialize serial communication: 
Serial.begin(9600); 
} 


void loop() { 
hallState = digitalRead(hall); 
if(cycle==true){ 
microsStart=micros(); 
} 
if(cycle==true){ 
usInterval = usElapsedUp/72; 
for (int i=0; i <= 36; i++){ 
digitalWrite(13,HIGH); 
delayMicroseconds(usInterval); 
digitalWrite(13,LOW); 
delayMicroseconds(usInterval); 
cycle = false; 
} 
} 

// compare the hallState to its previous state 
if (hallState != lasthallState) { 
// if the state has changed, increment the counter 
if (hallState == HIGH) { 
    teethCounter++; 
    if(teethCounter==24){ 
    cycle = true; 
    cycles++; 
    teethCounter=0; 
    usElapsedUp = usElapsed; 

    } 

    Serial.print("Tooth count: "); 
    Serial.print(teethCounter); 
    Serial.print(" Cycles: "); 
    Serial.print(cycles); 
    Serial.print(" Time: "); 
    Serial.print(usElapsedUp); 
    Serial.print(" Interval: "); 
    Serial.println(usInterval); 
    } 
    microsStop=micros(); 
    usElapsed=microsStop-microsStart; 
    } 
// save the current state as the last state, 
//for next time through the loop 

    lasthallState = hallState; 
    } 

Wie kann ich berechnen und ab wo kann ich Triggerpunkte nehmen?

If(event happens==true){ 
digitalWrite(13,HIGH); 
} 
If(event happens==false){ 
digitalWrite(13,LOW); 
} 

If it helps to understand here is a block diagram

+0

Sie benötigen eine Art von Funktion, die von 24 bis 36 konvertiert; da dies kein 1: 1-Mapping ist. Woher kommen die zusätzlichen 12 Impulse? –

+0

Möchten Sie von der 24-Puls-Frequenz * auf eine 36-Puls-Frequenz umrechnen? –

+0

Ja, genau das brauche ich –

Antwort

2

Solange Sie verstehen, dass Sie nie 36 Impulse pro Umdrehung Genauigkeit mit 24 Puls/Umdrehung erhält Lage sein werden, können Sie dies tun, die ein gemeinsamer Trick aus dem Bressenham Algorithmus abgeleitet sind . Diese Lösung geht davon aus, dass Sie sich über die Position Sorgen machen.

Nun wird dies Impulse in Echtzeit erzeugen, im Gegensatz zu Ihrem Code, der Impulse auf blockierende Weise erzeugt, ich glaube nicht, dass das Verlieren von Impulsen Ihre ursprüngliche Absicht war.

Dieser Code erzeugt keine gleichmäßigen Impulse, 1 von 3 Messungen erzeugt 2 Impulse. Ein anderer Weg wäre, die Durchschnittsgeschwindigkeit zu berechnen und einen Hardware-Timer zu programmieren, um die 36 Impulse pro Umdrehung mit Interrupts zu simulieren, aber diese Route würde wahrscheinlich (meiner Erfahrung nach) immer zu einem vollständigen Synchronisationsverlust führen die tatsächliche Position des Rades und was Ihre korrigierte Tick-Zählung meldet. Es gibt auch strenge Geschwindigkeitsbereiche, die Sie respektieren müssen, wenn Sie diese Route gehen, auch dies wird schwere Latenz Probleme zu Ihrer Anwendung einführen.

1: Ändern Sie den Inkrementwert auf 36, und die gesamte Umdrehungszahl auf 24/36.
2: Ändern Sie die Schritt Erkennung auf einen Schwellenwert von 24. 3: Ich versuche zu verstehen, warum Sie diese 36/24 Sache tun wollen, und kann nicht. So kann Ihre Laufleistung variieren

// compare the hall State to its previous state 
// to declared outside of loop() 
// int smallCounter; 
// PULSE_WIDTH as small positive pulse with in us 
// 
if (hallState != lasthallState) { 
    // if the state has changed, increment the counter 
    smallCounter += ((hallState == HIGH) ? 36 : 0); 
    // ... I'm assuming that the serial prints you had here were just here for debugging. 
    lasthallState = hallState; 
} 
// 
// reporting for each step below 
// 
if (smallCounter >= 24) 
{ 
    smallCounter -= 24; 
    if (++teethCounter >= 36) { 
    cycle = true; 
    cycles++; 
    teethCounter=0; 
    usElapsedUp = usElapsed; 

    } 
    digitalWrite(13,HIGH); 
    delayMicroseconds(PULSE_WIDTH); 
    digitalWrite(13,LOW); 
    delayMicroseconds(PULSE_WIDTH); // this is probably not needed. 
}