Hi Everyone,
I'm working on a project, that will have 1 master talking to 16 slaves. The idea is that I have 16 targets where one will randomly turn RED and another one BLUE. Airsoft player must shoot the target that correspond to their team's color. Once a target is hit, it will be turned OFF, and another of the same color will be turned ON, ready to be shot.
it somehow works, but for whatever reason, when a target is hit, it will sometime record 2 or even 3 point for that single hit ...
The slaves are "hit sensor" for an Airsoft target system. The target will illuminate red or blue. corresponding team need to shoot at the target. The principle of operation of the target sensor is as follow:
The slave are Pro Mini. They each have 2 red LEDs, 2 blue LEDs and a piezo element as the sensing element. The master will send either a '1' (Red Target) or a '2' (Blue Team).
The piezo is connected to the pin that has Interrupt 0. When a '1' or a '2' is received, the Interrupt is enabled. When the piezo senses a hit, a feedback value of 99 is set (arbitrary value) and the interrupt is disabled. LEDs are all turned OFF. The Arduino will then wait for a request from the master. Once that request comes in, Feedback is sent and the value is brought back to 0.
I have stripped down and modified my Master program, in order to simply send a '1' or a '2' to a certain station. Setup switch will allow to change that station, with the use of the "INC" and "DEC" button.
The "Enter" and "Next" will send a '1' or a '2' to that station.
I have connected a protocol sniffer: the first time I send, let's say a '2', the commend goes thru, the Blue LEDs turn ON. If I hit the sensor, the Master will read back '99' indicating it got it. On the protocol analyzer, you can see that there is a delay of about 200,000 uSeconds between the time the LED is turned ON and the time the Hit is recorded. So far so good.
(See "First Capture.JPG" & "Second Capture.JPG")
If I send another '2', the slave gets it, but reply right away with a returned value of '99'. That does not make as the sensor did not get hit, and its "feedback" value was set to '0'
(see "Third Capture.JPG")
Here is the code of the Master:
#include <LiquidCrystal.h>
#include <I2C.h>
// Initialize I/O used
int Setup = 2;
int Enter = 3;
int Next = 4;
int Inc = 5;
int Dec = 6;
int RS = 7;
int EN = 8;
int D4 = 9;
int D5 = 10;
int D6 = 11;
int D7 = 12;
int Start = 13;
int Stop = 14;
int ReceivedHit = 0;
int Station = 1;
boolean Started = 0;
int c = 0;
String Line1 = "";
String Line2 = "";
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
void setup() {
pinMode(Setup,INPUT);
pinMode(Enter,INPUT);
pinMode(Next,INPUT);
pinMode(Inc,INPUT);
pinMode(Dec,INPUT);
pinMode(EN,OUTPUT);
pinMode(RS,OUTPUT);
pinMode(D4,OUTPUT);
pinMode(D5,OUTPUT);
pinMode(D6,OUTPUT);
pinMode(D7,OUTPUT);
pinMode(Start,INPUT);
pinMode(Stop,INPUT);
lcd.begin(16, 2);
//Serial.begin(9600);
I2c.begin();
I2c.setSpeed(0);
I2c.timeOut(1000);
Line1 = "Station:" + String(Station);
Line2 = " ";
LCD_Routine();
}
void loop()
{
if (digitalRead(Setup) == 1)
{
Line1 = "Select station";
Line2 = "Station:"+ String(Station);
LCD_Routine();
ReceivedHit = 0;
ChooseStation();
delay(25);
}
if (Started == 1)
{
if (digitalRead(Stop) == 1)
{
Started = 0;
}
else
{
Running();
}
}
if (Started == 0)
{
if (digitalRead(Start) == 1)
{
Started = 1;
}
}
}
void Running()
{
delay(25);
ReadStation();
if (digitalRead(Next) == 1)
{
I2c.write(Station,1); // value of 1 is for Red LED
}
while(digitalRead(Next) ==1)
{
}
if (digitalRead(Enter) == 1)
{
I2c.write(Station,2); // value of 2 is for Blue LED
}
while(digitalRead(Enter) ==1)
{
}
}
void ChooseStation()
{
if(digitalRead(Inc) ==1)
{
Station = Station +1;
if (Station > 8)
{
Station = 1;
}
Line1 = "Station:"+ String(Station);
LCD_Routine();
while (digitalRead(Inc) == 1)
{
}
}
if(digitalRead(Dec) ==1)
{
Station = Station -1;
if (Station <1 )
{
Station = 8;
}
Line1 = "Station:"+ String(Station);
LCD_Routine();
while (digitalRead(Dec) == 1)
{
}
}
}
void ReadStation()
{
I2c.read(Station,1); // request 1 byte from Station
delay(50);
while(I2c.available())
{
c = I2c.receive();
if (c == 99) // if equal 99, means that this station recorded a hit
{
ReceivedHit = ReceivedHit +1;
Line1 = "";
Line2 = "Received Hits: " + String(ReceivedHit);
LCD_Routine;
c = 0;
while(I2c.available())
{
int c = I2c.receive();
}
}
}
}
void LCD_Routine()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(Line1);
lcd.setCursor(0, 1);
lcd.print(Line2);
}
and the Slave's code:
#include <Wire.h>
#define I2C_SLAVE_ADDRESS 0x3
// Address of the slave
int HitSensor = 2; // the pin that the Piezo is attached to
int BlueLED1 = 3; // the pin that the Blue LED is attached to
int RedLED1 = 4; // the pin that the Red LED is attached to
int BlueLED2 = 10; // the pin that the Blue LED is attached to
int RedLED2 = 11; // the pin that the Red LED is attached to
byte ByteRcvd = 0;
int NewDataFlag = 0;
byte Feedback = 0;
void setup()
{
// initialize the button pin as a input:
pinMode(HitSensor, INPUT);
// initialize the LED as an output:
pinMode(BlueLED1, OUTPUT);
pinMode(RedLED1, OUTPUT);
pinMode(BlueLED2, OUTPUT);
pinMode(RedLED2, OUTPUT);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent); // register event
Wire.onRequest(requestEvent); // register event
}
void loop()
{
if (Feedback ==99)
{
digitalWrite(BlueLED1, LOW);
digitalWrite(RedLED1, LOW);
digitalWrite(BlueLED2, LOW);
digitalWrite(RedLED2, LOW);
}
}
void receiveEvent(int howMany)
{
while(Wire.available()) // loop through all but the last
{
int x = Wire.read(); // receive byte as an integer
ByteRcvd = x;
NewDataFlag = 1;
}
delay(50);
if (NewDataFlag ==1)
{
if (digitalRead(HitSensor) ==0)
{
switch (ByteRcvd)
{
case 3:
Feedback = 0;
detachInterrupt(0);
digitalWrite(BlueLED1, LOW);
digitalWrite(RedLED1, LOW);
digitalWrite(BlueLED2, LOW);
digitalWrite(RedLED2, LOW);
ByteRcvd = 0;
NewDataFlag = 0;
break;
case 1:
Feedback = 0;
attachInterrupt(0,OnInterrupt, RISING);
digitalWrite(BlueLED1, LOW);
digitalWrite(RedLED1, HIGH);
digitalWrite(BlueLED2, LOW);
digitalWrite(RedLED2, HIGH);
ByteRcvd = 0;
NewDataFlag = 0;
break;
case 2:
Feedback = 0;
attachInterrupt(0,OnInterrupt, RISING);
digitalWrite(BlueLED1, HIGH);
digitalWrite(RedLED1, LOW);
digitalWrite(BlueLED2, HIGH);
digitalWrite(RedLED2, LOW);
ByteRcvd = 0;
NewDataFlag = 0;
break;
default:
break ;
}
}
}
}
void requestEvent()
{
Wire.write(Feedback);
Feedback = 0;
}
void OnInterrupt()
{
detachInterrupt(0);
Feedback = 99;
}
Anyone has a solution for me ??? I'm totally puzzled !
should you need more info, let me know.



