Showing posts with label arduino. Show all posts
Showing posts with label arduino. Show all posts

Thursday, 11 April 2024

Oddest Ball magic trick

 Having only seen the Oddest Ball magic trick in action, we're not 100% sure of what goes into it. But it's relatively simple to take a guess, and make something similar (even if it's not an exact copy).

But the basic idea is to have a long, thin "box" into which we'll have some holes, into each of which we place a golf ball (or similar-sized ball). Underneath one of the holes, we'll have a light-dependent resistor (LDR) and use this to detect whether the ball is present in the hole above.



Creating the box is relatively straight-forward: drop the design (above) onto the laser cutter and carve it out of 3mm mdf.

then quickly assemble the box and glue together using PVA glue


Some masking tape along the edges holds everything in place, while the glue dries.
Now, below the hole that will contain our red ball, we glue a small "drum" with a hole for an LDR (light dependent resistor) in the base. The idea is that when the ball is in place on top of the box, it will block all light from reaching the LDR.

When the ball is picked up, light will flood into the drum, and cause the resistance of the LDR to increase. We'll be able to detect this change in light level, using a voltage divider to create a variable "analogue" signal into a pin of a microcontroller.

When the LDR changes and we can detect that the ball has been lifted off the base, we'll generate a signal (and maybe trigger a siren or buzzer or similar alarm on the device itself).

Wednesday, 3 April 2024

And now for something completely different

 Just as our previous Nerd Club blog would often jump around between topics and ideas, so - it seems - this one is destined to do the same!

You see, we're still working on our Full Title electronic jousting game.
We've got some re-scaled minis (80% of full-scale from Highland Miniatures) that look much better on our jousting arena, and some different sized complete-loop timing belts (840mm and 920mm) which help improve the look and feel of things.

But the butterfly mind strikes again. And we're focussed on something completely different! (but a much simpler, smaller, self-contained project). 

For many years, a few of us have been attending the Blue Sky Music Open Mic nights, in and around Worthing. They're run by a smashing guy called Beany (and his wife Beth) and they're fantastic fun. And it's a true open-mic; not just singing, but performing, spoken word, poetry and even.... magic.

I always fancied having a go at performing some magic and have been watching a few performances from comedy magician Craig Petty. I really like his style, and love the way he goes into great depth with not just his tricks, but his performance advice too. When I invite others up to play when it's my turn to play a few songs, most open-mic jam sessions end up slightly chaotic, but we all have a bit of a laugh. So I thought I'd try something similar with a magic routine.

This one - called "Oddest Ball" - looks like a great "opener"

I love the comedy effect - and everyone immediately "gets" the gag. The only downside is that at over a hundred quid for a one-off laugh, it's a bit pricey! (I know that professional magicians "price in" how many times they get to use a prop and may come to a different conclusion).

But the hardware behind this seems pretty simple. And there's probably even a way we could improve of this - as well as produce it for a fraction of the £100+ price tag. I'm thinking of even having some kind of bluetooth-aware app running for the performance - so use the app to play some spooky "magic music" though the same P.A. system running the walk-around microphones. Then, when the appropriate ball is lifted, have the app play a loud siren/klaxon sound through the P.A. (rather than have to provide and power a built-in klaxon device).

In truth, we'll probably incorporate both.
But that's the basic idea - some hardware that can detect when a ball is lifted from above a sensor (LDR immediately springs to mind) that then triggers a super-loud klaxon sound. Nice and simple......

.... now where did I put those Arduino Mini boards that have been hanging around for the last five years or so...?

Sunday, 3 March 2024

Driving a nema-17 stepper motor

 Ok, we're not messing about now.
Yes, it was always a gamble that using a cheap 28BYJ-48 stepper motor with a laser cut home-made gear and a super-glued length of timing belt to make a continuous loop might not work. And it turns out it didn't.

Sure, we could add some kind of spring rollers to push the belt against the drive gear to help reduce slippage. But right at the very start of this project, we suspected this might happen...


So we're not going to waste spend any more time cobbling together something that may or may not work -it's time to focus on the end result here, not tinker with possibles and maybes (however interesting it might be to try out lots of different ideas). It's time to do it properly (as we probably should have done in the first place!) and use a "proper" stepper motor, and a "proper" closed loop timing belt and remove as many points of weakness/failure from the system as possible.

There are a few common-fixed-length closed loop timing belts on the market - the largest I could find (at a reasonable cost and able to deliver quickly) was 610mm. They are available in multi-packs of different sized belts:




These come with T2 pulleys for use with any common 3d printer kit.
Which means we're going to be driving our nema-17 stepper motor using an A4988 driver board.

(whether we go for the full 12V or stick with our preferred 9V, we'll have to wait and see, but the principle is pretty much the same not matter which supply voltage we eventually go with)

The nice thing about the A4988 board is that we don't need to worry about investigating coils and working out step sequences and making sure we drive the coils in the correct sequence and so on. You simply provide a direction signal and a step pulse and each time the step pin rises from low-to-high, the board sends the appropriate signals to advance the stepper motor by one step (in the appropriate direction).

There's also an Arduino library that allows you to send single, individual step commands - so we can run a function on a timer-based interrupt which checks to see if the motor should be running, and sends the appropriate pulse-step if necessary - this will allow us to run our code without having to worry about "blocking functions" or the microcontroller becoming unresponsive while the motor is turning.

As before, the first step is to just get our motor spinning in response to a single input condition - we can then expand this for use with a closed-loop belt and to make our "racetrack" for a remake of the classic GW game Full Tilt.


const int stepPin = 8;
const int dirPin = 9;
int delay_ms = 1;
int potValue = 0;

void setup() {
    pinMode(stepPin,OUTPUT);
    pinMode(dirPin,OUTPUT);
}

void loop() {

    digitalWrite(dirPin,HIGH);
    for(int x = 0; x < 200; x++) {
        digitalWrite(stepPin,HIGH);
        delay(delay_ms);
        digitalWrite(stepPin,LOW);
        delay(delay_ms);
        getSpeed();
    }
    delay(100);

    // change rotation direction
    digitalWrite(dirPin,LOW);
    for(int x = 0; x < 200; x++) {
        digitalWrite(stepPin,HIGH);
        delay(delay_ms);
        digitalWrite(stepPin,LOW);
        delay(delay_ms);
        getSpeed();
    }
    delay(100);
}

void getSpeed(){
    // read the speed input pot and set the speed value as appropriate
    potValue = analogRead(A0);
    delay_ms = map(potValue, 0, 1023, 1, 25);
}

The end result is a variable speed motor, which we can use a simple potentiometer to control to speed of rotation.



At slow speeds, the stepping becomes almost visible, and the noise from the motor becomes very noticeable. At higher speeds, the motor is less "noisy" but at its fastest, the motor is clearly moving too quickly for our purposes - probably great if you're driving a CNC or a 3d printer, to be able to move the head around so quickly, but for us, we'd much rather a slower "top speed" and a quieter operation.

There are driver boards out there that specialise in ultra-quiet operation. If it comes to it, we might give this some consideration. But before we do that, there is still one option available to us..... microstepping.

Friday, 1 March 2024

Testing a stepper motor driven belt loop

 Everything seems to be coming along quite nicely already.
We managed to get a stepper driver up and running (relatively) easily. Sure, it needs its own power rather than being driven off the puny usb port supply, but other than that simply swapping out some LEDs for a motor and everything worked as it should! So now it's time to try it out with the actual belt drive....



Oh dear.
Nothing. Or that's how it seemed at first. There was the tiniest little hum of activity coming from the motor, suggesting it was trying to do something. So I moved the belt(s) out of the way.

And, sure enough, the motor was trying to spin - it just didn't have enough power to push the belt around the track. Despite using low-friction bearings and trying to minimise the load on the motor, running it at 5V (off a phone charger power supply) just wasn't quite enough to get things moving.

So we tried bumping the power up and supplied (just the motor) with 9V from a power adapter (being careful to isolate the power to/from the Arduino and keep that separate - in the fullness of time we'd probably have a single power supply and run the Arduino off a step-down converter, but for now we'll keep things simple by keeping the two power supplies separate).



It looks like our motor is getting enough power now and preventing it from stalling. But the extra power isn't pushing the belt around - it's just causing the teeth to slip. So we need some kind of spring or something to help push the belt against the gear, to prevent it slipping.
There's no guarantee that will work - it's still possible that the belt will slip. But it's quite obvious that without something to hold the belt against the gear, this thing is never going to spin around!

As for the short video length?
Well, that's because when I tried to squeeze the belt against the gear (to simulate it being held by a spring) this happened.....


D'oh!

Thursday, 29 February 2024

Back to square one

It does feel very much like we're going back to basics on a lot of things.
Like learning to drive stepper motors again using darlington arrays.
A few years ago this was bread-and-butter do-it-in-your-sleep kind of stuff. But it's been a while. And lots has been learned. And lots has been forgotten. So we're having to get re-acquainted with the whole driving motors thing all over again.

We're also switching platforms.
For many years, I stuck steadfastly with my PIC microcontrollers. I still maintain they are far superior to the (often more fragile) AVR/ATMega microcontrollers. And when I first joined nerd club, Arduino was still very much in its infancy - and, coming from an industrial electronics background, I much favoured PICs over AVR for pretty much everything.

But the Arduino ecosystem is quite mature now.
And lots of people are familiar with it, and its bootloader sequence, and just how easy it is for hobbyists to just buy some very basic equipment and get coding with it. Not so the (rather more specialised) PIC.

So, while I'm not giving up on PICs, for hobby projects and for sharing with others, I'll probably default to Arduino for microcontroller stuff. For you guys ;-)

We're got our closed loop belt system finally built and ready for testing



What we need to do now is make that little motor in the middle spin, and see if it can drive the belt around in a loop....

We're using a 28BYJ-48 stepper motor (they're plentiful and super cheap and can run on anything from 5V up to 12V - the higher voltages giving a little more "welly" and supplying a bit more torque). 
Internally, the stepper motor is wired like this:



To get the motor to spin, we need to energise the coils in a specific sequence.
Each coil is connected at the mid point to a permanent, fixed power supply. So to energise coil one, we need to drive the pin connected to the end of coil one to ground. We then need to energise one of the other coils (probably coil 3) and we do this by disconnecting the first pin then driving the pin for coil 3 to ground.
By driving the pin for coil 2 to ground, we basically invert the electro-magnetic pole across the vertical coil, then lastly we drive the last pin to ground to complete the "step sequence".



That's a very basic explanation of how to make the stepper spin. The truth is, there are "inbetween steps". You can make the motor turn a "half-step" by energising two coils together (say one AND three). This will cause the motor to turn half-way between the positions between coil 1 and coil 3.

Because two coils are energised at the same time, this actually provides a little more power to the motor. So we'll make sure to use the half-step approach (energise two coils at once) but only ever power two coils at a time (so getting the speed/performance of full-step sequence, but the power/torque of half-stepping and energising two coils at a time).


To drive the coils to ground, we'll connect each end of the coil to a ULN2803A darlington array.


The common ground is connected to pin 8.
The "freewheeling diode" on pin 9 is to handle any "back-emf" generated by energising then disconnecting coils in the motor. We can connect this to our motor power supply to safely handle any "spikes" in the motor coils.

Now Arduino has a build in stepper motor library, but it's pretty crude and uses "blocking functions". That is to say, you wire everything up, tell the microcontroller how many steps you want it to move the motor by, and the code prevents any further code execution until all the steps have taken place. We basically want to set our motor spinning and keep it spinning until we interrupt it with some kind of input signal.
So we're going to write our own simple stepper motor driver than can be interrupted at any point.

To test our coil sequence, instead of connecting the motor (which requires its own dedicated power supply, because it draws so much current) we'll connect up some LEDs and watch them light up in sequence, to make sure our code is at least triggering the correct outputs in the right sequence.


int coil1_pin = 2;
int coil2_pin = 3;
int coil3_pin = 4;
int coil4_pin = 5;
int start_stop_pin = 10;

int current_step = 1;
int step_direction = 1;

void setup() {
  // when a pin is made an output, it defaults to LOW
  pinMode(coil1_pin, OUTPUT);
  pinMode(coil2_pin, OUTPUT);
  pinMode(coil3_pin, OUTPUT);
  pinMode(coil4_pin, OUTPUT);

  // this is just a test pin; pull low to make the motor spin
  pinMode(start_stop_pin, INPUT_PULLUP);
}

void loop() {

  // to be useful we'd probably set a flag to say if the motor
  // should be running or not; here we'll just read a pin state
  int i = digitalRead(start_stop_pin);
  if(i == LOW) {
    nextStep();
  }
}

void disableCoils() {
  // remember we're driving a ULN2803A darlington array
  // we're not driving to motor directly, so a high
  // signal energises the coil (drives the output of the
  // array low) - to turn off all coils, all pins should be low
  digitalWrite(coil1_pin, LOW);
  digitalWrite(coil2_pin, LOW);
  digitalWrite(coil3_pin, LOW);
  digitalWrite(coil4_pin, LOW);
}

void nextStep() {
  current_step += step_direction;
  if(current_step > 4) { current_step = 1; }
  if(current_step < 1) { current_step = 4; }
  disableCoils();

  switch(current_step) {
    case 1:
    digitalWrite(coil4_pin, HIGH);
    digitalWrite(coil2_pin, HIGH);
    break;

    case 2:
    digitalWrite(coil2_pin, HIGH);
    digitalWrite(coil3_pin, HIGH);
    break;

    case 3:
    digitalWrite(coil3_pin, HIGH);
    digitalWrite(coil1_pin, HIGH);
    break;

    case 4:
    digitalWrite(coil1_pin, HIGH);
    digitalWrite(coil4_pin, HIGH);
    break;
  }

  // add a delay because if you try to drive
  // the stepper motor too quickly it will chatter
  // (if testing with LEDs, make this a longer delay)
  delay(500);
}


Here's what the flashing LED sequence looks like:


Replacing the LEDs with our stepper motor, and the result (with a modified delay between steps) looks like this:


So we've got our motor spinning, albeit in a very crude way.
But it's a start - now to hook it up to our belt drive and see if we can't get the belt to move around the track....