The Spinning Fortunagraph

hello

wanted to share a project I have recently completed called The Spinning Fortunagraph as part of the Fantascopic Fair held at The Kazimier (Sep 26). The device is an interactive wheel of fortune that can (if interpreted correctly by an operator) predict the future. Well... sort of. It draws heavily on tarot card symbols and luck. The fortunagraph utilises 2 arduinos (i am sure we could have done it with one but i ran out of time and had a spare arduino). The first works as an RFID reader and reads the RFID cards placed onto it - there are 8 cards in total with each one triggering a different animation. This is done using an external piece of software called Modul8 and the RFID signal is converted to MIDI for this. The animation triggered symbolises the tarot card with which the user will be playing. The second arduino is inside the machine and works predominatly as an optical tachometer, its job is to measure the speed of the rotation and control variable video / audio parameters. It was really interesting and challenging building it, especially since it was exhibited as part of a much bigger evening with over 600 guests attending - so it needed to be pretty robust. The device comes with an operator - a sort of wise guru who explains the different symbols as they come and interprets the final outcomes meaning - with suprising accuracy.

I have built a little site that has a short video below:

http://www.fortunagraph.co.uk

thank you very much to Asa Calow and Adrian McEwen for all the help

Wow, just wow. Awesome project! I really love the quality and design, its shows how much care and effort you must have put into this. Also, It would be greatly appreciated if you posted more build info and pictures. Once again fantastic job!

thank you for your kind workds - it did take a while. I worked mainly on the arduino and video side of things whilst my friend did all the construction, we built the whole thing in a 3D program first and were able to work to the same specifications. All the components of the piece only came together and worked less than 24 hours before the event itself. Will gather all the bits of code and schematics and post them up soon.

sorry to take so long - here is the code for the fortunagraph. It takes the tachometer reading and outputs that as a midi cc value at the same time the value is used to control the brightness of LED’s plugged into it. There is also a little snippet of code there that triggers a midi noteON once the tachometer gets over a certain speed (in the video online this part of the code is responsible for triggering the moving images projected onto the surface of the machine once the fortunagraph gets up to speed). Appologies for the messiness of the code - it is a cut and paste combination of a lot of different ideas.

  /*
 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually. A status LED is connected
 * to pin 12. Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * 
 */
//#define DEBUG      

int ledPin = 13;                // IR LED connected to digital pin 13
int statusPin = 12;  // LED connected to digital pin 12
int lightPin1 = 6;
int lightPin2 = 9;
int lightPin3 = 10;
int lightPin4 = 11;
int brightness = 0;
int delay_time = 40; // delay for this amount each write cycle.
int noteDown = LOW;
byte MIDI_channel = 0;
byte cc_number = 0;
byte incomingByte;
byte button;
byte note;
byte printing_byte = 0;
int Value = 0;
int midi_pitch = 0;
int mappedrpm = 0;
int state=0;
#ifdef DEBUG
const int DEBUG_RATE = 9600;        // Serial debugging communicates at 9600 baud
const int SERIAL_PORT_RATE = DEBUG_RATE;
#else
const int MIDI_BAUD_RATE = 31250;   // MIDI communicates at 31250 baud
const int SERIAL_PORT_RATE = MIDI_BAUD_RATE;
#endif



volatile byte rpmcount;
volatile int status;

unsigned int rpm;

unsigned long timeold;

// flag switching stuff
boolean top_speed_reached = false;
int on_threshold = 70;
int off_threshold = 50;

void rpm_fun()
{
  //Each rotation, this interrupt function is run twice, so take that into consideration for 
  //calculating RPM
  //Update count
  rpmcount++;

  //Toggle status LED   
  if (status == LOW) {
    status = HIGH;
  } 
  else {
    status = LOW;
  }
  digitalWrite(statusPin, status);
}

void setup()
{
  state = 0;

  Serial.begin(SERIAL_PORT_RATE);
  //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
  //Triggers on FALLING (change from HIGH to LOW)
  attachInterrupt(0, rpm_fun, FALLING);

  //Turn on IR LED
  pinMode(ledPin, OUTPUT); 
  digitalWrite(ledPin, HIGH);

  //Use statusPin to flash along with interrupts
  pinMode(statusPin, OUTPUT);

  rpmcount = 0;
  rpm = 0;
  timeold = 0;
  status = LOW;


}

void loop()
{
  //Update RPM every second
  delay(800);
  //Don't process interrupts during calculations
  detachInterrupt(0);
  //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
  //happened once per revolution instead of twice. Other multiples could be used
  //for multi-bladed propellers or fans in this case the tachometer has 20 holes for greater accuracy
  rpm = 3*1000/(millis() - timeold)*rpmcount;
  timeold = millis();
  rpmcount = 0;
  attachInterrupt(0, rpm_fun, FALLING);
  brightness = map(rpm, 0, 36, 0, 255);
  analogWrite(lightPin1, brightness);
  analogWrite(lightPin2, brightness);
  analogWrite(lightPin3, brightness);
  analogWrite(lightPin4, brightness);
  printing_byte = map(rpm, 0, 36, 0, 127);{
  midiOUT(0xB0, 7, printing_byte);
  }
   
  if (!top_speed_reached) {
    if (printing_byte >= on_threshold) {
      top_speed_reached = true;
      midiOUT(0x90, 60, 127);
    }
  } else {
    if (printing_byte <= off_threshold) {
      top_speed_reached = false;
      midiOUT(0x90, 45, 127);
    }
  }
  
}




  //Write it out to serial port
  //Restart the interrupt processing
  


void midiOUT(char command, char value1, char value2) {
  Serial.print(command, BYTE);
  Serial.print(value1, BYTE);
  Serial.print(value2, BYTE);

}