// include the SPI library:
#include <SPI.h>
// L9958 slave select pins for SPI
#define SS_M4 14
#define SS_M3 13
#define SS_M2 12
#define SS_M1 11
// L9958 DIRection pins
#define DIR_M1 2
#define DIR_M2 3
#define DIR_M3 4
#define DIR_M4 7
// L9958 PWM pins
#define PWM_M1 9
#define PWM_M2 10 // Timer1
#define PWM_M3 5
#define PWM_M4 6 // Timer0
// L9958 Enable for all 4 motors
#define ENABLE_MOTORS 8
int pwm1, pwm2, pwm3, pwm4;
int dir1, dir2, dir3, dir4;
int ms = 0;
int cs = 0;
const int joyup = 15;
const int joydown = 16;
const int joyleft = 17;
const int joyright = 18;
const int joypress = 19;
//const int coin = 21;
const int front = 20;
const int left = 22;
const int clawup = 23;
const int clawdown = 24;
unsigned long currentime = 0;
int credit = 0;
int charge = 0;
long int gametime = 10;
void setup() {
Serial.begin(9600);
unsigned int configWord;
// put your setup code here, to run once:
pinMode(SS_M4, OUTPUT); digitalWrite(SS_M4, HIGH); // HIGH = not selected
pinMode(SS_M3, OUTPUT); digitalWrite(SS_M3, HIGH);
pinMode(SS_M2, OUTPUT); digitalWrite(SS_M2, HIGH);
pinMode(SS_M1, OUTPUT); digitalWrite(SS_M1, HIGH);
// L9958 DIRection pins
pinMode(DIR_M1, OUTPUT);
pinMode(DIR_M2, OUTPUT);
pinMode(DIR_M3, OUTPUT);
pinMode(DIR_M4, OUTPUT);
// L9958 PWM pins
pinMode(PWM_M1, OUTPUT); digitalWrite(PWM_M1, LOW);
pinMode(PWM_M2, OUTPUT); digitalWrite(PWM_M2, LOW); // Timer1
pinMode(PWM_M3, OUTPUT); digitalWrite(PWM_M3, LOW);
pinMode(PWM_M4, OUTPUT); digitalWrite(PWM_M4, LOW); // Timer0
// L9958 Enable for all 4 motors
pinMode(ENABLE_MOTORS, OUTPUT); digitalWrite(ENABLE_MOTORS, HIGH); // HIGH = disabled
// set to max current limit and disable ISR slew limiting
configWord = 0b0000010000001100;
SPI.begin();
SPI.setBitOrder(LSBFIRST);
SPI.setDataMode(SPI_MODE1); // clock pol = low, phase = high
// Motor 1
digitalWrite(SS_M1, LOW);
SPI.transfer(lowByte(configWord));
SPI.transfer(highByte(configWord));
digitalWrite(SS_M1, HIGH);
// Motor 2
digitalWrite(SS_M2, LOW);
SPI.transfer(lowByte(configWord));
SPI.transfer(highByte(configWord));
digitalWrite(SS_M2, HIGH);
// Motor 3
digitalWrite(SS_M3, LOW);
SPI.transfer(lowByte(configWord));
SPI.transfer(highByte(configWord));
digitalWrite(SS_M3, HIGH);
// Motor 4
digitalWrite(SS_M4, LOW);
SPI.transfer(lowByte(configWord));
SPI.transfer(highByte(configWord));
digitalWrite(SS_M4, HIGH);
// Reduce the PWM frequency to about 8kHz
// Note, this will screw up the timer functions that use Timer0 such as millis()
setPwmFrequency(PWM_M1, 8);
setPwmFrequency(PWM_M3, 8);
pinMode(joyup, INPUT_PULLUP);
pinMode(joydown, INPUT_PULLUP);
pinMode(joyleft, INPUT_PULLUP);
pinMode(joyright, INPUT_PULLUP);
pinMode(joypress, INPUT_PULLUP);
//pinMode(coin, INPUT_PULLUP);
pinMode(front, INPUT_PULLUP);
pinMode(left, INPUT_PULLUP);
pinMode(clawup, INPUT_PULLUP);
pinMode(clawdown, INPUT_PULLUP);
attachInterrupt(2, coin, LOW); //Will interrupt the program to add credits when coin is incerted.
}
// *******************************************
// ************** Main Loop ******************
// *******************************************
void loop() {
ms = 200; //Motor speed
cs = 255; //Claw strength
charge = 1;
Serial.print("Credit = ");
Serial.println(credit);
if (credit >= charge)
{
currentime = millis();
while ((gametime * 10000) >= (millis() - currentime))
{
if (digitalRead(joypress) == HIGH)
{
digitalWrite(ENABLE_MOTORS, LOW);
while (digitalRead(clawdown) == LOW)
{
analogWrite(PWM_M3, ms); digitalWrite(DIR_M3, 0);
}
analogWrite(PWM_M3, 0); digitalWrite(DIR_M3, 0);
digitalWrite(ENABLE_MOTORS, HIGH);
delay(2000);
digitalWrite(ENABLE_MOTORS, LOW);
analogWrite(PWM_M4, cs); digitalWrite(DIR_M4, 0);
delay(3000);
while (digitalRead(clawup) == LOW)
{
analogWrite(PWM_M3, ms); digitalWrite(DIR_M3, 1);
}
analogWrite(PWM_M3, 0); digitalWrite(DIR_M3, 0);
while (digitalRead(left) == LOW)
{
analogWrite(PWM_M2, ms); digitalWrite(DIR_M2, 0);
}
analogWrite(PWM_M2, 0); digitalWrite(DIR_M2, 0);
while (digitalRead(front) == LOW)
{
analogWrite(PWM_M1, ms); digitalWrite(DIR_M1, 1);
}
analogWrite(PWM_M1, 0); digitalWrite(DIR_M2, 1);
delay(5000);
analogWrite(PWM_M4, 0); digitalWrite(DIR_M4, 0);
digitalWrite(ENABLE_MOTORS, HIGH);
delay(8000);
credit = credit - charge;
gametime = 0;
}
else
{
digitalWrite(ENABLE_MOTORS, LOW);
while (digitalRead(joyup) == HIGH)
{
analogWrite(PWM_M1, ms); digitalWrite(DIR_M1, 0);
}
analogWrite(PWM_M1, 0); digitalWrite(DIR_M1, 0);
while (digitalRead(joydown) == HIGH)
{
analogWrite(PWM_M1, ms); digitalWrite(DIR_M1, 1);
}
analogWrite(PWM_M1, 0); digitalWrite(DIR_M1, 0);
while (digitalRead(joyright) == HIGH)
{
analogWrite(PWM_M2, ms); digitalWrite(DIR_M2, 1);
}
analogWrite(PWM_M2, 0); digitalWrite(DIR_M2, 0);
while (digitalRead(joyleft) == HIGH)
{
analogWrite(PWM_M2, ms); digitalWrite(DIR_M2, 0);
}
analogWrite(PWM_M2, 0); digitalWrite(DIR_M2, 0);
digitalWrite(ENABLE_MOTORS, HIGH);
}
}
digitalWrite(ENABLE_MOTORS, LOW);
while (digitalRead(clawdown) == LOW)
{
analogWrite(PWM_M3, ms); digitalWrite(DIR_M3, 0);
}
analogWrite(PWM_M3, 0); digitalWrite(DIR_M3, 0);
digitalWrite(ENABLE_MOTORS, HIGH);
delay(2000);
digitalWrite(ENABLE_MOTORS, LOW);
analogWrite(PWM_M4, cs); digitalWrite(DIR_M4, 0);
delay(3000);
while (digitalRead(clawup) == LOW)
{
analogWrite(PWM_M3, ms); digitalWrite(DIR_M3, 1);
}
analogWrite(PWM_M3, 0); digitalWrite(DIR_M3, 0);
while (digitalRead(left) == LOW)
{
analogWrite(PWM_M2, ms); digitalWrite(DIR_M2, 0);
}
analogWrite(PWM_M2, 0); digitalWrite(DIR_M2, 0);
while (digitalRead(front) == LOW)
{
analogWrite(PWM_M1, ms); digitalWrite(DIR_M1, 1);
}
analogWrite(PWM_M1, 0); digitalWrite(DIR_M2, 1);
delay(5000);
analogWrite(PWM_M4, 0); digitalWrite(DIR_M4, 0);
digitalWrite(ENABLE_MOTORS, HIGH);
delay(8000);
credit = credit - charge;
}
}
// ************** End Main Loop ******************
void setPwmFrequency(int pin, int divisor) {
byte mode;
if (pin == 5 || pin == 6 || pin == 9 || pin == 10) { // Timer0 or Timer1
switch (divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 64: mode = 0x03; break;
case 256: mode = 0x04; break;
case 1024: mode = 0x05; break;
default: return;
}
if (pin == 5 || pin == 6) {
TCCR0B = TCCR0B & 0b11111000 | mode; // Timer0
} else {
TCCR1B = TCCR1B & 0b11111000 | mode; // Timer1
}
} else if (pin == 3 || pin == 11) {
switch (divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 32: mode = 0x03; break;
case 64: mode = 0x04; break;
case 128: mode = 0x05; break;
case 256: mode = 0x06; break;
case 1024: mode = 0x7; break;
default: return;
}
TCCR2B = TCCR2B & 0b11111000 | mode; // Timer2
}
}
void coin()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 500)
{
credit = credit + 1;
}
last_interrupt_time = interrupt_time;
}