Pages: [1]   Go Down
Author Topic: Help with code, Hdd Pov Clock  (Read 779 times)
0 Members and 1 Guest are viewing this topic.
Argentina
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi to everyone!
I'm building my own HDD POV CLOCK. Finally I have all the hardware up and running and it's time to code. Before codeing the clock I've started with something simpler like a circle splitted in 4. I almost got it, but my problem is that I can't get the circle to stay "static" it keeps spinning very slowly!! I posted a video to show it better.. Do you think it's a software problem or a hardware problem?

About the hardware:
- Hdd running at 7220 rpm -> This is very stable, sometimes it goes to 7214 or 7223 but no beyond that
- Magnet sticked to hard drive plate
- Hall effect sensor through a schmitt trigger (40106) to interrupt 0 of Arduino
- ULN2003 to turn on the leds

The video showing the bug:


And my code:
Code:
int leds=8; //Led strip on pin 8, connect to 12v from ATX trough ULN2003

unsigned long tiempoAnterior = 0;
unsigned long tiempoLeds = 0;
unsigned long tiempoVuelta=0;
volatile  unsigned long vueltas=0;
int ledState=LOW;

void setup()
{
  attachInterrupt(0, rpm_fun, FALLING); //interrupt 0 -> pin 2
}

void loop()
{
  unsigned long tiempoActual= micros();
  if(vueltas>=20)
  {
    tiempoVuelta = (tiempoActual-tiempoAnterior) / vueltas; //Each turn takes aproximately 8310 uS
    tiempoAnterior = tiempoActual; 
    vueltas=0;   
  }

  if(tiempoActual-tiempoLeds>= (tiempoVuelta/4)-4)           //tiempoVuelta/4 -> Split each revolution time into 4
  {                                                          //This (-4) factor is a correction factor showed in the video, best value I've found
    tiempoLeds=tiempoActual;   //Last time Leds blinked      //If I put (-0) the circle spins faster,
    ledState = !ledState;                                   //And if I put (-5) of below, the circle starts spinng the other way
    digitalWrite(leds, ledState);
  }
}

void rpm_fun()
{
  vueltas++;
}

Thanks to everyone!
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 201
Posts: 8646
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think it would work if you synchronized the LED loop with the interrupt.  By re-starting the LED timer with each interrupt you should be able to keep the blinking locked to the position of the platter.  Something like this:

Code:
int leds=8; //Led strip on pin 8, connect to 12v from ATX trough ULN2003

unsigned long tiempoAnterior = 0;
volatile unsigned long tiempoLeds = 0;
unsigned long tiempoVuelta=0;
volatile  unsigned long vueltas=0;
int ledState=LOW;

void setup()
{
  attachInterrupt(0, rpm_fun, FALLING); //interrupt 0 -> pin 2
}

void loop()
{
  unsigned long tiempoActual = micros();
  if(vueltas>=20)
  {
    tiempoVuelta = (tiempoActual-tiempoAnterior) / vueltas; //Each turn takes aproximately 8310 uS
    tiempoAnterior = tiempoActual; 
    vueltas=0;   
  }

  if(tiempoActual-tiempoLeds >= (tiempoVuelta/4))           //tiempoVuelta/4 -> Split each revolution time into 4
  {                                                     
    tiempoLeds=tiempoActual;   //Last time Leds blinked
    ledState = !ledState;
    digitalWrite(leds, ledState);
  }
}

void rpm_fun()
{
  vueltas++;
  tiempoLeds = micros();
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Argentina
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi John! Thanks for your answer, and sorry for answering so late, I didn't see the notification... I realized that the problem was exactly what you're pointing. I could solve it making the loop() run only once with each interruption, kinda worked, but is not perfect, i'm still working on that smiley-grin
I'm going to try aproching the problem the way you pruposed, I think is more efficient!

this is what I've so far

Thanks!
Logged

Pages: [1]   Go Up
Jump to: