Mäta hastigheten på Nerf Dart (4 / 4 steg)
Steg 4: elektronik
När en dart passerar ljusbarriären blockerande IR-LED nuvarande sjunker omedelbart till noll. Vid denna tid börjar de micro controller räkna mikrosekunder tills den andra LED är blockerad. Som vi vet avståndet mellan lysdioderna kan vi beräkna dart hastigheten.
Värdet skickas till en LED driver chip (SAA 1064) så visas den på sju segment display ligger på sidan av fat.
Jag använde en Arduino UNO ladda upp följande kod till Atmega:
#include "Wire.h" / / I2C kontroll
#include "Bounce.h"
byte diaplayAddr = 0x70 >> 1. Adressen till I2C kontroll
int digitBytes [16] = {63 6, 91, 79, 102, 109, 125, 7, 127, 111, 119, 124, 57, 94, 121, 113}; 0 1 2 3 4 5 6 7 8 9, decimaltecken = +128
ljusbarriären
int LSFrontPin = A0; ljusbarriären framtill på fat
int LSBackPin = A1; ljusbarriären på baksidan av fat
int TriggerPin = 11;
flyta meanVal = 0;
flyta meanCount = 0;
Datenverarbeitung
int LSFrontVal = 0;
int LSBackVal = 0;
int BaseLineFront = 0;
int BaseLineBack = 0;
tröskel, att erkänna en dart
int TriggerFront = 0;
int TriggerBack = 0;
mäta hastigheten
int measuringBack = 0;
flyta längd = 0.173; m
int loopTime = 100; tid av mätpunkten i micro sekunder
osignerade långa measureLoops = 0;
osignerade långa hjärtslag = 0;
flyta TempBaseLineFront = 0;
flyta TempBaseLineBack = 0;
Studsa försmak = Bounce (TriggerPin, 10);
void setup() {
Serial.BEGIN(9600);
Wire.BEGIN(); starta upp I2C bussen
Delay(500);
createDisplay();
pinMode (LSFrontPin, indata);
pinMode (LSBackPin, indata);
pinMode (TriggerPin, indata);
Delay(1000);
skapa en baslinje
för (int ii = 0; ii < 100; ii ++) {
TempBaseLineFront = TempBaseLineFront + analogRead(LSFrontPin);
TempBaseLineBack = TempBaseLineBack + analogRead(LSBackPin);
Delay(10);
}
BaseLineFront = (int)(TempBaseLineFront / 100);
TriggerFront = (int)(0.8*BaseLineFront);
BaseLineBack = (int)(TempBaseLineBack / 100);
TriggerBack = (int)(0.8*BaseLineBack);
Visar att man aktiverar görs: blinkar tre gånger med baslinjen värden
writeNumber (TriggerFront, 500);
Delay(200);
writeNumber (TriggerBack, 500);
Delay(200);
writeNumber (888, 500);
Delay(200);
writeNumber (888, 500);
Delay(200);
writeNumber (888, 500);
Delay(200);
measuringBack = 1; starta mätning och vänta på dart
}
void createDisplay() {
Wire.beginTransmission(diaplayAddr);
Wire.write(B00000000); entgegen
Subadressing: B00000001 = siffran 1, Subadressing: B00000010 = siffran 2, Subadressing: B00000011 = siffran 3, Subadressing: B00000100 = siffran 4
Wire.write(B00110111); styra byte (dynamisk modus på 9 mA)
Wire.endTransmission();
Wire.beginTransmission(diaplayAddr);
Wire.write(1); instruktion byte - första siffran till kontroll är 1 (höger)
Wire.write(digitBytes[0]); siffran 1 (HS)
Wire.write(digitBytes[1]); siffran 2
Wire.write(digitBytes[2]); siffran 3
Wire.endTransmission();
Wire.beginTransmission(diaplayAddr);
Wire.write(1); instruktion byte - första siffran till kontroll är 1 (höger)
Wire.write(digitBytes[9]); siffran 1 (HS)
Wire.write (digitBytes [0] + 128); siffran 2 + Dezimal punkt
Wire.write(digitBytes[1]); siffran 3
Wire.endTransmission();
}
void writeNumber (int nummer, int waitTime) {
creat nummer och Visa för waitTime ms
int digit1 = antal/100.
int digit2 = (antal - (digit1 * 100)) / 10;
int digit3 = nummer - digit1 * 100 - digit2 * 10;
Serial.println(Number);
Serial.Print ("digit1:"); Serial.println(digit1);
Serial.Print ("digit2:"); Serial.println(digit2);
Serial.Print ("digit3:"); Serial.println(digit3);
Wire.beginTransmission(diaplayAddr);
Wire.write(1); instruktion byte - första siffran till kontroll är 1 (höger)
Wire.write(digitBytes[digit3]); siffran 1 (HS)
Wire.write (digitBytes [digit2] + 128); siffran 2 + decimalkommat
Wire.write(digitBytes[digit1]); siffran 3
Wire.endTransmission();
Delay(waitTime);
Wire.beginTransmission(diaplayAddr);
Wire.write(1); instruktion byte - första siffran till kontroll är 1 (höger)
Wire.write(0); siffran 1 (HS)
Wire.write(0); siffran 2 + decimalkommat
Wire.write(0); siffran 3
Wire.endTransmission();
}
void heartBeatBeat() {
låter den decimala punkten blinka
Wire.beginTransmission(diaplayAddr);
Wire.write(1); instruktion byte - första siffran till kontroll är 1 (höger)
Wire.write(0); siffran 1 (HS)
Wire.write(128); siffran 2 + decimalkommat
Wire.write(0); siffran 3
Wire.endTransmission();
Delay(100);
Wire.beginTransmission(diaplayAddr);
Wire.write(1); instruktion byte - första siffran till kontroll är 1 (höger)
Wire.write(0); siffran 1 (HS)
Wire.write(0); siffran 2 + decimalkommat
Wire.write(0); siffran 3
Wire.endTransmission();
}
void loop() {
Pulsslag intervall
om (millis() > (heartBeat + 5000)) {
heartBeat = millis();
heartBeatBeat();
}
Läs på-knappen
Taster.Update();
int TasterStatus = Taster.read();
osignerade långa längd = Taster.duration();
om ((TasterStatus == HIGH) & & (varaktighet < 2000)) {
writeNumber((int)(meanVal*10/meanCount), 1000);
}
annat if (TasterStatus == hög) {
Serial.println("reset");
writeNumber (0, 500); Delay(200);
writeNumber (0, 500); Delay(200);
writeNumber (0, 500); Delay(200);
meanVal = 0;
meanCount = 0;
Delay(500);
}
delayMicroseconds(loopTime);
om (digitalRead(TriggerPin) == hög) {Serial.println("Trigger!");}
om (measuringBack == 1) {
Pfeil wurde noch nicht detektiert
LSBackVal = analogRead(LSBackPin);
om (LSBackVal < TriggerBack) {measuringBack = 0; measureLoops = micros(); Serial.Print ("starta Trigger:"); Serial.println(TriggerBack); Serial.println(LSBackVal); }
}
annat
{
dart upptäcktes, men anländer inte i fronten
LSFrontVal = analogRead(LSFrontPin);
om (LSFrontVal < TriggerFront) {
osignerade långa stopTime=micros();
flyta deltaTus = (float)(stopTime-measureLoops);
deltaTus = deltaTus / 1.0e6;
flyta mSpeed = längd / deltaTus;
measuringBack = 1;
Serial.println(measureLoops);
Serial.println(stopTime);
Serial.println(deltaTus);
Serial.println(mSpeed);
meanCount = meanCount + 1.
meanVal = meanVal + mSpeed;
Serial.println(meanVal);
Serial.println(meanCount);
writeNumber((int)(mSpeed*10), 500);
Delay(200);
}
}
#Reset efter 1 s
om ((measuringBack == 0) & & (micros() > (measureLoops + 1000000)))
{
measuringBack = 1;
}
}