The laser is not connected to the Arduino. It sits in a modified toy gun which came with sound and thus had a battery (4.5 V).
Here is the code (the post with all the code was to long, so I had to shorten it a bit):
CalibrationDashboard.h:
class CalibrationDashboard
{
public:
static CalibrationDashboard& Instance(); // Class method as the only access to the Singleton Object
int getAnalog();
bool getButton();
bool getRedLed();
void setRedLed(bool onOff);
bool getGrnLed();
void setGrnLed(bool onOff);
protected:
unsigned long btnLastMillis;
bool btnLastResult;
private:
static CalibrationDashboard* pInstance; // Static variable holding the pointer to the only instance of this
CalibrationDashboard();
};
CalibrationDashboard.cpp:
#ifndef pinconf
#include "pinconf_MVP1.h"
#endif
#include "CalibrationDashboard.h"
CalibrationDashboard& CalibrationDashboard::Instance(){
//static Cleanup cleanup;
if (CalibrationDashboard::pInstance == nullptr)
CalibrationDashboard::pInstance = new CalibrationDashboard();
return *CalibrationDashboard::pInstance;
}
// There is only this private constructor, no public one!
CalibrationDashboard::CalibrationDashboard(){
pinMode(buttonPin, INPUT); // 10k ohm pulldown resistor attached
pinMode(ledRedPin, OUTPUT);
pinMode(ledGrnPin, OUTPUT);
}
/**
Returns current value from the defined analog Pin
*/
int CalibrationDashboard::getAnalog(){
return analogRead(analogPin);
}
/**
while-friendly: returns true until button is pushed
*/
bool CalibrationDashboard::getButton(){
if (CalibrationDashboard::btnLastMillis - millis() > 20)
{
CalibrationDashboard::btnLastMillis = millis();
if(digitalRead(buttonPin)==LOW)
{
CalibrationDashboard::btnLastResult = true;
return true;
}
else
{
CalibrationDashboard::btnLastResult = false;
return false;
}
}
return CalibrationDashboard::btnLastResult;
}
/**
Get and set status of attached LEDs
*/
bool CalibrationDashboard::getRedLed(){
return digitalRead(ledRedPin);
}
void CalibrationDashboard::setRedLed(bool onOff){
digitalWrite(ledRedPin, onOff);
}
bool CalibrationDashboard::getGrnLed(){
return digitalRead(ledGrnPin);
}
void CalibrationDashboard::setGrnLed(bool onOff){
digitalWrite(ledGrnPin, onOff);
}
Target.h:
#include "Arduino.h"
#include <Servo.h>
#include "CalibrationDashboard.h"
#include <assert.h>
class Target
{
public:
Target(int servoPin, int ldrPin);
~Target();
void adjustServo(CalibrationDashboard* calDb);
bool evalStatus();
void reInit();
byte getUpPos();
byte getDownPos();
private:
bool _isInited;
Servo _srv;
int _ldrPin;
bool _alive;
long _msTargetDied;
int _ldrThreshold;
byte _upPos;
byte _downPos;
//int _calibrateLdr();
int _calibrateLdr(int calibReadings, long readIntervall);
bool _chkLdrHit();
void _updPosition();
};
Target.cpp:
#include "Target.h"
/**
Constructor
*/
Target::Target(int servoPin, int ldrPin){
...}
void Target::reInit(){
…
}
Target::~Target(){
…
}
void Target::adjustServo(CalibrationDashboard* calDb){
const byte BLINK_INT = 100;
const byte DEBOUNCE = 15;
long ms;
int angle;
ms = 0;
angle = calDb->getAnalog();
Target::_srv.write(constrain(angle, 0, 180));
// adjust servo using analog reference
while (calDb->getButton()) {
// adjust down position until button is pressed
angle = map(calDb->getAnalog(), 0, 1023, 0, 180);
if (Target::_srv.read() != angle) Target::_srv.write(angle);
// Red LED blinking during this
if (millis() - ms > BLINK_INT) {
ms = millis();
calDb->setRedLed(!calDb->getRedLed());
}
delay(DEBOUNCE);
}
Target::_upPos = angle;
// confirm with red LED on
calDb->setRedLed(true);
delay(2000);
calDb->setRedLed(false);
delay(100);
while (calDb->getButton()) {
// adjust up position until button is pressed
angle = map(calDb->getAnalog(), 0, 1023, 0, 180);
if (Target::_srv.read() != angle) Target::_srv.write(angle);
// Green LED blinking during this
if (millis() - ms > BLINK_INT) {
ms = millis();
calDb->setGrnLed(!calDb->getGrnLed());
}
delay(DEBOUNCE);
}
Target::_downPos = angle;
// confirm with green LED on
calDb->setGrnLed(true);
delay(2000);
calDb->setGrnLed(false);
delay(100);
Target::_isInited = true;
}
/**
Returns status of the target: true = active; false = dead
Check the Hit-Status
*/
bool Target::evalStatus(){
...
}
/**
Returns calculated correction factor * average value of readings + 1/2 * range
int calibReadings - number of readings for average
long readIntervall - pause between readings in ms
*/
int Target::_calibrateLdr(int calibReadings, long readIntervall){
...
}
/**
Returns whether LDR-resistance is below defined Threshold
If Threshold is passed, Target is hit and then !_alive thereafter
*/
bool Target::_chkLdrHit(){
...}
/**
Adjusts the servo according to the target's _alive status
*/
void Target::_updPosition(){
…
}
byte Target::getUpPos(){
…
}
byte Target::getDownPos(){
…
}
Laserschiessen.ino:
// Testausgaben zentral steuern:
#define logging
//Bibliotheken
#define __ASSERT_USE_STDERR
#include <assert.h>
// #include <EEPROM.h>
// Ton-Definitionen
#ifndef pitches_h
#include "pitches.h"
#endif
// Pin-Belegung auf Arduino Mega mit 10 LDR+Servos
#ifndef pinconf
#include "pinconf_MVP1.h"
#endif
#ifndef CalibrationDashboard_h
#include "CalibrationDashboard.h"
#endif
#ifndef Target_h
#include "Target.h"
#endif
#ifndef Lasergame_h
#include "Lasergame.h"
#endif
// Prepare Targets
//int targetInfo[cntSens][2] {{sp0, ldr0}, {sp1, ldr1}, {sp2, ldr2}, {sp3, ldr3}, {sp4, ldr4}, {sp5, ldr5}, {sp6, ldr6}, {sp7, ldr7}, {sp8, ldr8}, {sp9, ldr9}};
Target t0(sp0, ldr0);
Target t1(sp1, ldr1);
Target t2(sp2, ldr2);
Target t3(sp3, ldr3);
Target t4(sp4, ldr4);
Target t5(sp5, ldr5);
Target t6(sp6, ldr6);
Target t7(sp7, ldr7);
Target t8(sp8, ldr8);
Target t9(sp9, ldr9);
Target* targets[cntSens] {&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9};
// CalibrationDashboard cdb;
CalibrationDashboard* calDbrd; // Singleton!
// - SETUP -------------------------------------------------------------------------------------------
void setup() {
// Serieller Monitor
Serial.begin(9600); // initialize serial communications at 9600 bps
#ifdef logging
Serial.println("- - - - - setup startet - - - - -");
#endif
// digitale Eingänge initialisieren
pinMode(btnY, INPUT_PULLUP);
#ifdef logging
Serial.println("Yellow Button bereit (startet Kalbrieren neu)");
#endif
pinMode(btnR, INPUT_PULLUP);
#ifdef logging
Serial.println("Red Button bereit (bricht laufendes Spiel ab)");
#endif
// Instanzen für Ziele erstellen
calDbrd = &calDbrd->Instance();
/*
for (int i = 0; i < cntSens; i++) {
targets[i] = new Target(targetInfo[i][0], targetInfo[i][1]);
#ifdef logging
Serial.print("Target Nr. "); Serial.print(i + 1); Serial.println(" erstellt");
#endif
delay(100);
}
*/
#ifdef logging
Serial.println("Ziele bereit");
#endif
// digitale Ausgänge
pinMode(redLed, OUTPUT);
digitalWrite(redLed, HIGH);
#ifdef logging
Serial.println("Rote Status-LED bereit (Spiel läuft)");
#endif
pinMode(grnLed, OUTPUT);
digitalWrite(grnLed, HIGH);
#ifdef logging
Serial.println("Grüne Status-LED bereit (Spiel bereit)");
#endif
// Info-Ton
tone(buzzPin, NOTE_C7, 500);
// Status LED ausgeschaltet initialisieren
digitalWrite(redLed, LOW); digitalWrite(grnLed, LOW);
// Servos kalibrieren
//calDbrd& = calDbrd->Instance();
for (int i = 0; i < cntSens; i++) {
targets[i]->adjustServo(calDbrd);
#ifdef logging
Serial.print("Target Nr. "); Serial.print(i + 1); Serial.println(" kalibriert");
#endif
tone(buzzPin, NOTE_C5, 250);
}
#ifdef logging
Serial.println("Ziele kalibriert");
#endif
digitalWrite(redLed, LOW); digitalWrite(grnLed, HIGH);
#ifdef logging
Serial.println("- - - - - setup fertig - - - - -");
#endif
}
// - LOOP ---------------------------------------------------------------------------------------------
void loop() {
// Yellow button starts the game
if (digitalRead(btnY) == HIGH) {
Serial.println("+ + + Spiel startet + + +");
Lasergame game(targets);
digitalWrite(redLed, HIGH); digitalWrite(grnLed, LOW);
Serial.println(sprintf("Spieldauer %f ms", game.start()/1000));
digitalWrite(redLed, LOW); digitalWrite(grnLed, HIGH);
Serial.println("+ + + Spiel beendet + + +");
}
}