2017-06-13 80 views
2

有人可以帮我用代码吗?我有一个24齿的扳机轮。每颗牙齿都由霍尔传感器记录,我需要Arduino模拟相应的24脉冲输入的36个脉冲输出。Arduino C++计算触发点

这里是我的代码与delayMicroseconds,但我不能使用delayMicroseconds,因为Arduino不明白大于16k微秒延迟。

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; 
    } 

我该如何计算并从哪里获取触发点?

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

你需要某种功能,从24转换为36;因为这不是1:1映射。额外的12个脉冲来自哪里? –

+0

是否要将24脉冲*频率*转换为36脉冲频率? –

+0

是的,那正是我需要的 –

回答

2

只要你明白,你将永远无法得到每转的精度36个脉冲,24脉冲/转,你能做到这一点,这是从Bressenham算法得出一个共同的伎俩。这个解决方案假定你关心这个位置。

现在,这将实时生成脉冲,而不是您的代码,它以阻塞的方式生成脉冲,我认为不会丢失脉冲是您的初衷。

该代码不会均匀生成脉冲,3个读数中的1个会生成2个脉冲。

另一种方式是,以计算平均速度和编程硬件计时器来模拟每匝36个脉冲,使用中断,但打算这条路线将可能(总是在我的经验)之间的同步的总损失最终车轮的实际位置以及您校正的滴答计数报告的内容。还有严格的速度范围,你必须尊重,如果去那条路线,这也会引入严重的延迟问题到您的应用程序。

1:将增量值更改为36,并将整个转数计为24/36。
2:将步骤检测更改为阈值24. 3:我试图理解为什么要做这个36/24的事情,而不能。所以,你的里程可能会有所不同

// 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. 
}