Schietkist V3 – Arduino build

schietkistv3

Een nieuw jaar, een nieuwe schietkist! Dit jaar geen versie met 10tallen meters kabels of handmatige besturing, maar een versie dat wordt bestuurd door een Arduino. De Arduino stuurt doormiddel van een een 433mhz Transmitter de code door die een kanaal op het relay board openzet. De Arduino is dan eigenlijk ook niet meer dan een geautomatiseerde afstandbediening die normaal gesproken bij de relay board wordt geleverd.

Deze schietkist is gebouwd voor 12 sloten, echter is het heel eenvoudig om extra relay boards toe te voegen. Er moet alleen wel voor worden gezorgd dat de relay boards luisteren naar andere codes, anders open je meerdere kanalen tegelijk.

Allereerst ben ik begonnen met het achterhalen van de codes die gebruikt worden bij de 12 channel relay board, door een Arduino te gebruiken met daarop aangesloten een 433Mhz RF ontvanger was het eenvoudig om de juiste codes te achterhalen. Standaard zit bij de Arduino software een sketch waarmee je de ontvangen data kan tonen van een RF receiver. De sketch is te vinden in de Arduino software via File –> Sketchbook –> libraries –> RCSwitch –> ReceiveDemo_Simple.

Adruino_software

De RF receiver die ik heb gebruik is een XY-MK-5V RF 433Mhz receiver en is voor €1 te koop via eBay.nl. Op de receiver zitten 4 aansluit punten, echter hoeven er maar 3 aangesloten te worden. Namelijk de GND, 5V en Data pin, hieronder een schematische tekening waarin te zien is hoe de receiver moet worden aangesloten.

RF433MHZ

arduino_setup_rf433mhz

Wanneer de sketch naar de Arduino is geüpload en de RF 433Mhz module is op de juiste manier aangesloten kan de serial monitor worden geopend, die ook te vinden is in de Arduino software. Als alles op de juiste manier is aangesloten en is ingesteld dan zouden de codes die de afstandbediening van de relay board uitzend moeten worden getoond in de serial monitor wanneer er een knop wordt ingedrukt op de afstandbediening. De output dat te zien is in de serial monitor is vergelijkbaar met wat hieronder wordt getoond.

code

Nu ik weet welke codes de afstandbediening uitzend kan ik een Arduino sketch maken waarin de codes automatisch worden gestuurd. Voor de transmitter heb ik gebruik gemaakt van de module die bij de receiver zat, tevens wilde ik op een scherm kunnen zien welk kanaal aan de beurt was, het signaal moest sterk zijn en moest er knop op waarmee het proces kon worden gestart. En dit alles in een mooie behuizing zodat het er ook nog eens leuk uitziet, dit resulteerde dan ook tot de volgende bestellijst:

Na enkele weken wachten waren de spullen geleverd en kon ik alles in elkaar zetten om de sketch te gaan maken. Omdat ik zelf heel weinig ervaring heb met scripten was het voornamelijk knip en plak werk van sketches die ik op internet heb gevonden. Het nadeel was hierin wel dat geen enkele sketch maar ook iets te maken had met wat ik wilde gaan doen met mijn sketch, echter na veel try & error is het gelukt om een sketch te maken die doet wat ik wil.

Om de LCD display te laten werken heb ik de library ‘LiquidCrystal’ gebruik, deze library is geschreven door F. Malpartida en is te downloaden op BitBucket. Bij deze library zit een uitgebreide handleiding waarin wordt uitgelegd hoe de LCD scherm aangesproken kan worden. Voor het aanspreken van de 433Mhz transmitter heb ik gebruik gemaakt van de standaard RCSwitch library die ook gebruikt is bij het uitlezen van de codes eerder in dit bericht. Voor de “lanceerknop” wordt ook gebruik gemaakt van een standaard library genaamd Wire, deze is ook te vinden in de Arduino software. De laatste versie van de Arduino Schietkist sketch is te vinden op mijn GitHub pagina, waarschijnlijk kan de code vele male efficiënter worden geschreven. Maar voor die ene keer in het jaar dat hij wordt gebruikt vind ik hem prima! Ik zal een aantal onderdelen uit de sketch toelichten zodat het een beetje duidelijk is wat de sketch uitvoert.

RCSwitch mySwitch = RCSwitch();
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

We beginnen met het definiëren van de variable mySwitch, zodat de Arduino weet dat als er mySwitch staat dat dan de tranmitter wordt bedoeld. Daarna definiëren we hoe de LCD display moet worden aangesproken, de waardes hiervan kunnen afhangen van welke type je hebt. Meer informatie over de verschillende waardes is te vinden op deze pagina.

unsigned long pauseOne = 2000; // Set pause time slot 1
unsigned long pauseTwo = 2000; // Set pause time slot 2
unsigned long pauseThree = 2000; // Set pause time slot 3

Omdat niet alle sloten direct af moeten gaan zijn er 12 variables gedefinieerd met daarachter een waarde in cijfers. Deze waarde staat voor het aantal millisecondes dat gewacht moet worden alvorens een nieuw kanaal wordt aangesproken, 1 minuut moet dan ook worden genoteerd als 60000 (1*60*1000). Het is echter belangrijk om er een unsigned long variable van te maken, wanneer dit namelijk niet wordt gedaan en de waarde is groter dan 32bits (4 bytes) dan wordt de waarde omgezet in een negatief getal. Wanneer de waarde is omgezet in een negatief getal, kan je jaren wachten maar zal er niets gebeuren.

  //Slot 1
  mySwitch.send(4019459, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 1 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseOne);

  //Slot 2
  mySwitch.send(4019468, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 2 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseTwo);

Voor elk kanaal heb ik een code blok gemaakt, hierin wordt de variable mySwitch aangesproken met de opdracht op een waarde te versturen. Dit zijn de waardes die we eerder hebben uitgelezen, tevens geef ik aan dat de waarde 24bit is zoals ook uit te lezen was toen we de codes gingen uitlezen. Op het LCD scherm wordt aangegeven welke kanaal aan de beurt is en daarna wordt de pauze ingeladen die we eerder hebben gedefinieerd.

/*
** Get the LCD I2C Library here: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/LiquidCrystal_V1.2.1.zip
*/

#include <RCSwitch.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

RCSwitch mySwitch = RCSwitch();
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int buttonPin = 2; // Set button
boolean currentState = LOW; // Current button state
boolean lastState = LOW; // Last button state

//See man page about unsigned long -- https://www.arduino.cc/en/Reference/UnsignedLong
//Pause time in ms, 1*60*1000 = 60000 = 1 minute
unsigned long pauseOne = 2000; // Set pause time slot 1
unsigned long pauseTwo = 2000; // Set pause time slot 2
unsigned long pauseThree = 2000; // Set pause time slot 3
unsigned long pauseFour = 2000; // Set pause time slot 4
unsigned long pauseFive = 2000; // Set pause time slot 5
unsigned long pauseSix = 2000; // Set pause time slot 6
unsigned long pauseSeven = 2000; // Set pause time slot 7
unsigned long pauseEight = 2000; // Set pause time slot 8
unsigned long pauseNine = 2000; // Set pause time slot 9
unsigned long pauseTen = 2000; // Set pause time slot 10
unsigned long pauseEleven = 2000; // Set pause time slot 11
unsigned long pauseTwelve = 2000; // Set pause time slot 12

void setup() {
  
  // Set Pin as INPUT
  pinMode(buttonPin, INPUT);
    
  // Used to type in characters
  Serial.begin(9600);
  
  // Initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.begin(16,2);
  
  // Quick 3 blinks of backlight 
    for(int i = 0; i< 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight();

  // Transmitter is connected to Arduino Pin #8
  mySwitch.enableTransmit(8);

  // Optional set pulse length.
  mySwitch.setPulseLength(500);
  
}

void loop() {
currentState = digitalRead(buttonPin);
  if (currentState == LOW && lastState == HIGH)
  {
  lcd.setCursor(1,0);
  lcd.print("Start Countdown");
  lcd.setCursor(0,1);
  lcd.print("1..............");
  delay(1000);

  lcd.setCursor(0,0);
  lcd.print("Start Countdown");
  lcd.setCursor(0,1);
  lcd.print("1...2..........");
  delay(1000);

  lcd.setCursor(0,0);
  lcd.print("Start Countdown");
  lcd.setCursor(0,1);
  lcd.print("1...2...3......");
  delay(1000);

  lcd.setCursor(0,0);
  lcd.print("Start Countdown");
  lcd.setCursor(0,1);
  lcd.print("1...2...3...NOW");
  delay(1000);

  //Slot 1
  mySwitch.send(4019459, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 1 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseOne);

  //Slot 2
  mySwitch.send(4019468, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 2 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseTwo);

  //Slot 3
  mySwitch.send(4019471, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 3 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseThree);

  //Slot 4
  mySwitch.send(4019504, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 4 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseFour);

  //Slot 5
  mySwitch.send(4019507, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 5 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseFive);

  //Slot 6
  mySwitch.send(4019516, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 6 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseSix);

  //Slot 7
  mySwitch.send(4019519, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 7 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseSeven);

  //Slot 8
  mySwitch.send(4019648, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 8 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseEight);
  
  //Slot 9
  mySwitch.send(4019651, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 9 ====");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseNine);

  //Slot 10
  mySwitch.send(4019660, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 10 ===");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseTen);

  //Slot 11
  mySwitch.send(4019663, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 11 ===");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseEleven);

  //Slot 12
  mySwitch.send(4019696, 24);
  lcd.setCursor(0,0);
  lcd.print("==== SLOT 12 ===");
  lcd.setCursor(0,1);
  lcd.print("===== FIRE =====");
  delay(pauseTwelve);
  }
  
  else if(currentState == HIGH && lastState == LOW){
  lcd.setCursor(0,0);
  lcd.print("System Activated");
  lcd.setCursor(0,1);
  lcd.print(" Push to start ");
  delay(1);
  }
  lastState = currentState;
}

Nu de sketch af is en lijkt te functioneren wordt het tijd om de Arduino inclusief extra modules/onderdelen netjes te gaan inbouwen in de behuizing. Allereerst is er een gaatje gemaakt voor de antenne en is er een gat gemaakt voor de push button het script op de Arduino kan worden gestart.

Daarna kon het LCD scherm erin, echter paste deze niet helemaal dus heb ik de connectie pinnen eraf gehaald en er kabels op gesoldeerd. Ook kon de transmitter erin en worden aangesloten aan de antenne en moesten er nog kabels worden gesoldeerd aan de push button. Toen de onderdelen op hun plek zaten kon alles worden aangesloten op de Arduino en worden uitgeprobeerd.

Onder de motorkap is het op deze manier aangesloten.

Transmitter-schema

Het gedeelte dat de codes verstuurd was nu helemaal klaar, alleen zonder ontvanger hebben we nog geen schietsysteem! De ontvanger gaat bestaan uit 3 field cases met op elke field case 4 aansluitpunten dat weer correspondeer met een kanaal op de 12 channel relay. Voor de field cases heb ik gekozen voor een plastic behuizing gemaakt van het materiaal ABS, deze heb ik gekocht via AliExpress. In de eerste field case komt de 12 channel relay te zitten, de andere 2 field cases worden aangesloten op de eerste field case doormiddel van een zelfgemaakte DB15 kabel. Naast de 12 channel relay komt er ook nog een power switch in de eerste field case en wordt er een test modus ingebouwd.

Ik ben begonnen met de power switch in te bouwen, de power switch bestaat uit een plus en een min connector waarop de batterij kan worden aangesloten en een SPDT switch (on – off – on) en twee LEDjes (groen = test mode / rood = arm mode). Met verschillende dikte boortjes heb ik de gaten in de plastic behuizing gemaakt zodat de onderdelen er netjes in konden worden geschroefd. Daarna was het de beurt om de onderdelen met elkaar te verbinden. Hoe de kabels zijn gesoldeerd is hieronder in de tekening te zien.

Power-Connector

Nadat de power switch klaar was heb ik de uitsnede gemaakt voor de DB15 connectors, door eerst alles netjes uit te tekenen op het stukje plastic was het heel eenvoudig om met een dremel + een vijltje de juiste formaat gaten te maken. In Photoshop heb ik een boor tekening gemaakt voor de speaker terminals en LED houders waar straks de ontstekers aan komen te hangen. Door de boor tekening uit te printen en strak op de plastic behuizing te plakken kon ik de gaten netjes boren.

Nu was het tijd om de kabels te gaan solderen in de eerste field case en deze ook direct aan te sluiten op de 12 channel relay. Alle min punten zijn aan elkaar gesoldeerd, aangezien dit de aarde is voor het systeem. De min kant van de LED lampen heb ik aangesloten aan de kabel bij de power connector dat weer gekoppeld is aan de test mode. De plus kant van de LED lampen is aangesloten aan de plus kant van de speaker terminal, tevens zit er een kabel aan de plus kant van de speaker terminal die naar een kanaal loopt op de 12 channel relay. Op de DB15 connectors heb ik 3 punten gepakt waar een aarde kabel aan is gesoldeerd, 1 punt wordt gebruikt voor de test mode en 4 punten voor 4 kanalen op de 12 channel relay. Om het duidelijker te maken heb ik een tekening gemaakt die iedereen snapt, voor de vergrote versie klik je op de afbeelding hieronder.

Fieldcase-Relay-v2-SMALL

Toen alle kabels waren gesoldeerd zoals is aangegeven in bovenstaande tekening was de eerste field case die de andere twee field cases aanstuurt helemaal af.

De twee andere field cases zijn een uit gekeelde versie van de eerste field case, met dezelfde boor tekening heb ik de gaten gemaakt voor de LED lampen en de speaker terminals. En er is één opening gemaakt voor de DB15 connector, meer is er niet nodig in deze field cases. De bekabeling binnenin is ook niet heel spannend, echter om het visueel goed te kunnen laten zien heb ik ook hiervan een tekening gemaakt.

Fieldcase-Clean-SMALL

Toen ook deze twee field cases klaar waren, kon de kabel worden gesoldeerd die straks de field cases met elkaar verbinden. Hiervoor heb ik een UTP kabel gepakt die volledig van koper is. Veel goedkope UTP kabels op rol zijn niet volledig van koper, let hier tijdens het kopen goed op anders ga je problemen krijgen tijdens het solderen!

En na vele uren solderen, debuggen, plannen herzien is de 3de schietkist klaar! Later heb ik nog een antenne geplaatst op de eerste field case aangezien het signaal niet altijd goed binnenkwam. Ik ben weer erg blij met deze versie en hoop dan ook dat het straks vlekkeloos gaat werken 🙂

 schietkiest_v3_31