Skip to content

Playing around with devices

New picture element

Wanter to test a neopixel strip. Some kind of controllable lightning system would make sense for a pinball machine.

Installed Adafruit_Neopixel library to Arduino IDE.

Loaded Adafruit Neopixel -> simple sample code from the Arduino IDE, and uploaded it to the XIAO-RP2040. Only thing that was changed was the defined PIN for the ledstrips data bus.

The code
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN        D2 // On Trinket or Gemma, suggest changing this to 1

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16 // Popular NeoPixel ring size

// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

#define DELAYVAL 5000 // Time (in milliseconds) to pause between pixels

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}

void loop() {
  pixels.clear(); // Set all pixel colors to 'off'

  // The first NeoPixel in a strand is #0, second is 1, all the way up
  // to the count of pixels minus one.
  for(int i=0; i<NUMPIXELS; i++) { // For each pixel...

    // pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
    // Here we're using a moderately bright green color:
    pixels.setPixelColor(i, pixels.Color(0, 150, 0));

    pixels.show();   // Send the updated pixel colors to the hardware.

    delay(DELAYVAL); // Pause before next pass through loop
  }
}

First strand of neopixels did not work. When we tried to control it with the above code, which should turn all leds to half bright green one by one, it instead turned the first led green, then it turned the same led white, followed by the next led turning blue, which was followed by the next led turning red. After that, the loop continued. Something was wrong, so we swapped to a different strip, and it seemed to work.

The things that could have caused this are faulty strip, or the strip using different logic than expected. The logic would be understandable, of the data bus is just an incremented array of led intesities, and the first strip expected 4 values per led and the last strip required only 3 values per led.

i.e. the dirrerence between these signals:

r-g-b-r-g-b-r-g-b-r-g-b-r-g-b-r-g-b-r-g-b-r-g-b
r-g-b-a-r-g-b-a-r-g-b-a-r-g-b-a-r-g-b-a-r-g-b-a

Especially if the RGB signal is out of order:

g-b-r-g-b-r-g-b-r-g-b-r-g-b-r-g-b-r-g-b-r-g-b-r
g-b-r-a-g-b-r-a-g-b-r-a-g-b-r-a-g-b-r-a-g-b-r-a

After getting the led strip to work, we tested how the code and the strip reacts to different lights and different number of leds.

Solenoids

Testing solenoids makes sense, as pinball machines are mostly just solenoids and relays.

I own many solenoids. Of different kinds. Some solenoids of them are needed for the pinball machines, so I needed to test how they work, and can they push the steel balls with enough speed and force to actually make the game interesting. So I hooked them up to a power source, and tested them. The actual code for them would require some kind of transistor to control the higher voltages that they need.

The solenoids that I have:

I played around with different solenoids, trying out their electricity consumption, strike power (agains a steel ball) and power against strings.

Solenoids with a string.

Granted, these tests have nothing to do with programming. These solenoids are just fed power directly from a power source. But solenoids are output devices, important for pinball machines, and these tests showcase how wimpy my solenoids are. These tests were done with the 12V pull solenoid.

Servo

To test a servomotor, I used my ball feeder test bed I had made previously. The point is to build a gate, that is attached to a servomotor. The servo should turn 90 degress to release a ball.

I had 3D printed the gate previously, and laser cut the test bed. Both of the were made too snug, so I needed to use a drill, a knife and a file to make them fit.

Programming a servo

Those clips show me using servo tester, but the same thing can easily be done with code. Here is the code for controlling the servo as a gate. The same code could easily be used with some ball detection mechanism, but this was tested with a button on the Quentorres board.

Code
#include <Servo.h>


Servo servo;

bool gateState = false;

#define GATE_OPEN 50
#define GATE_CLOSED 180

#define PIN_SERVO_DATA 28

#define PIN_GUTTER_DETECTOR 27

int lastButtonPressTime = 0;
int lasstGateOpenTime = 0;


void openGate() {

  int currentButtonPressTime = millis();

  if (gateState == false) {
    gateState = true;
    lastGateOpenTime = millis();
    servo.write(GATE_OPEN);
  }
}


void setup() {
  // put your setup code here, to run once:

  pinMode(PIN_SERVO_DATA, OUTPUT);
  pinMode(PIN_GUTTER_DETECTOR, INPUT);

  servo.attach(PIN_SERVO_DATA);

  attachInterrupt(digitalPinToInterrupt(PIN_GUTTER_DETECTOR), openGate, RISING);

  Serial.begin(9600);
}

void loop() {

  if (gateState == true) {
    int currentTime = millis();

    if (currentTime > lastButtonPressTime + 1000) {
      servo.write(GATE_CLOSED);
      gateState = false;
    }
  }

}

The code uses an interrupt to read the signal from a button, and then opens the gate. The code automatically closes the gate after a second has passed. This check is done in the normal loop.