586,121 active members*
3,375 visitors online*
Register for free
Login
Results 1 to 2 of 2
  1. #1
    Join Date
    Jan 2009
    Posts
    484

    $22 (Or less) DIY Charge pump

    So, I have been piecing together my CNC electronics for a while and putzing with different designs. I made a "Charge pump" detection circuit using a 555 Timer and some bits and bobs... which was definitely cheap. I designed it around an 11Khz signal only to find out later that EMC was only going to give me a 6K signal. It still worked... but only with ~90% reliability. It was cheap as chips but I wanted to try something different which is what started this design, and I figured I would post it because it's also not too expensive and is easily done by anyone likely to be reading this section of the forum, LOL.

    The basic parts are an Arduino Nano (although the full size Arduino would be just fine) and a commonly available "Relay module".

    You can get both for under $20 if you shop around but you can get them from Amazon, with Prime shipping for around $22.00

    Relay Module
    Amazon.com: SainSmart 4-Channel Relay Module: Car Electronics

    Arduino Nano
    Amazon.com: RioRand

    Anyway, I stole some code from the Arduino forum that could read a frequency input to a pin and used that to have the system simply turn on the relays when anything over 2Khz was present. That's high enough to be pretty certain it's an intentional signal.

    To prevent spurious signals from the PC booting up from being passed through I also set up a 60 second delay before the unit becomes "active" and allows the relays to activate. (Probably unnecessary)

    On mine, I used a 4 relay module (Spindle/Stepper Power/20V Mist Supply) so it will power down all motors and the mist system when it turns off. The signal line goes through my E-stop.

    The last relay will be wired to an input on my breakout board to tell EMC when a mechanical Estop has been triggered. I could just as easily use the normally open side of the E-stop switch too.

    Code:
    // Frequency counter sketch, for measuring frequencies low enough to execute an interrupt for each cycle
    // Connect the frequency source to the INT0 pin (digital pin 2 on an Arduino Uno)
    
    volatile unsigned long firstPulseTime;
    volatile unsigned long lastPulseTime;
    volatile unsigned long numPulses;
    int ledPin = 13;
    int relay1Pin = 3;
    int relay2Pin = 4;
    int relay3Pin = 5;
    int relay4Pin = 6;
    void isr()
    {
      unsigned long now = micros();
      if (numPulses == 1)
      {
        firstPulseTime = now;
      }
      else
      {
        lastPulseTime = now;
      }
      ++numPulses;
    }
    
    void setup()
    {
    Serial.begin(19200);    // this is here so that we can print the result
    digitalWrite (relay1Pin, HIGH);
    digitalWrite (relay2Pin, HIGH);
    digitalWrite (relay3Pin, HIGH);
    digitalWrite (relay4Pin, HIGH);
    pinMode(ledPin, OUTPUT);
    pinMode(relay1Pin, OUTPUT);
    pinMode(relay2Pin, OUTPUT);  
    pinMode(relay3Pin, OUTPUT);  
    pinMode(relay4Pin, OUTPUT);  
      digitalWrite (ledPin, HIGH);
      Serial.println("Delaying 60 Seconds to allow PC Boot");
      delay (10000);
        digitalWrite (ledPin, LOW);
      Serial.println("50 Seconds Remaining");
      delay (10000);
        digitalWrite (ledPin, HIGH);
      Serial.println("40 Seconds Remaining");
      delay (10000);
        digitalWrite (ledPin, LOW);
      Serial.println("30 Seconds Remaining");
      delay (10000);
        digitalWrite (ledPin, HIGH);
      Serial.println("20 Seconds Remaining");
      delay (10000);
      digitalWrite (ledPin, LOW);
      Serial.println("10 Seconds Remaining");
      delay (10000);
        digitalWrite (ledPin, HIGH);
      Serial.println("Charge Pump Started");
    }
    
    // Measure the frequency over the specified sample time in milliseconds, returning the frequency in Hz
    float readFrequency(unsigned int sampleTime)
    
    { numPulses = 0;                      // prime the system to start a new reading
      attachInterrupt(0, isr, RISING);    // enable the interrupt
      delay(sampleTime);
      detachInterrupt(0);
      return (numPulses < 3) ? 0 : (1000000.0 * (float)(numPulses - 2))/(float)(lastPulseTime - firstPulseTime);
    }
    
    
    void loop()
    {
    
      
      float freq = readFrequency(100);
        if ( freq > 2000)
    {
      digitalWrite (ledPin, HIGH);
      digitalWrite (relay1Pin, LOW);
      digitalWrite (relay2Pin, LOW);
      digitalWrite (relay3Pin, LOW);
      digitalWrite (relay4Pin, LOW);
      
      Serial.print("ChargePump Active. Current Frequency: ");
      Serial.println(freq);
    }
    else
    {
      digitalWrite (ledPin, LOW);
      digitalWrite (relay1Pin, HIGH);
      digitalWrite (relay2Pin, HIGH);
      digitalWrite (relay3Pin, HIGH);
      digitalWrite (relay4Pin, HIGH);
      Serial.print("ChargePump Inactive. Current Frequency: ");
      Serial.println(freq);
    }
    
      delay(100);
    }

    So, there ya go. I have been toying with the idea of using the relays to control other logic (IE, coolant only works when spindle is on, etc) in the system but with EMC it's kind of redundant anyway. I just though others might find it interesting or might have suggestions for improvement/simplification.
    Q: How many tools does it take before a simple task becomes a project?
    A: Just one. I'm the Tool that turns a simple task in to a project.

  2. #2
    Join Date
    Jan 2009
    Posts
    484

    Re: $22 (Or less) DIY Charge pump

    Update to the code. Pretty minor, I just changed the initial state of the input pin. It was too prone to floating and was picking up crosstalk from the wire next to it, enough that the two wires going to the E-Stop was transferring enough signal that it would still trigger the detector with the switch off. 'Doh! Anyway, pulling it up with the internal 20K pullup resistor was sufficient.

    Code:
    //*Frequency*counter*sketch,*for*measuring*frequencies*low*enough*to*execute*an*interrupt*for*each*cycle
    //*Connect*the*frequency*source*to*the*INT0*pin*(digital*pin*2*on*an*Arduino*Uno)
    
    volatile*unsigned long firstPulseTime;
    volatile*unsigned long lastPulseTime;
    volatile*unsigned long numPulses;
    int ledPin = 13;
    int relay1Pin = 3;
    int relay2Pin = 4;
    int relay3Pin = 5;
    int relay4Pin = 6;
    void isr()
    {
    **unsigned long now = micros();
    **if (numPulses == 1)
    **{
    ****firstPulseTime*=*now;
    **}
    **else
    **{
    ****lastPulseTime*=*now;
    **}
    **++numPulses;
    }
    
    void setup()
    {
    Serial.begin(19200);    // this is here so that we can print the result
    digitalWrite (relay1Pin, HIGH);
    digitalWrite (relay2Pin, HIGH);
    digitalWrite (relay3Pin, HIGH);
    digitalWrite (relay4Pin, HIGH);
    pinMode(2,INPUT_PULLUP); 
    pinMode(ledPin, OUTPUT);
    pinMode(relay1Pin, OUTPUT);
    pinMode(relay2Pin, OUTPUT);  
    pinMode(relay3Pin, OUTPUT);  
    pinMode(relay4Pin, OUTPUT);  
    **digitalWrite (ledPin, HIGH);
    **Serial.println("Delaying 60 Seconds to allow PC Boot");
    **delay (10000);
    ****digitalWrite (ledPin, LOW);
    **Serial.println("50 Seconds Remaining");
    **delay (10000);
    ****digitalWrite (ledPin, HIGH);
    **Serial.println("40 Seconds Remaining");
    **delay (10000);
    ****digitalWrite (ledPin, LOW);
    **Serial.println("30 Seconds Remaining");
    **delay (10000);
    ****digitalWrite (ledPin, HIGH);
    **Serial.println("20 Seconds Remaining");
    **delay (10000);
    **digitalWrite (ledPin, LOW);
    **Serial.println("10 Seconds Remaining");
    **delay (10000);
    ****digitalWrite (ledPin, HIGH);
    **Serial.println("Charge Pump Started");
    }
    
    //*Measure*the*frequency*over*the*specified*sample*time*in*milliseconds,*returning*the*frequency*in*Hz
    float readFrequency(unsigned int sampleTime)
    
    {*numPulses*=*0;**********************// prime the system to start a new reading
    **attachInterrupt(0, isr, RISING);    // enable the interrupt
    **delay(sampleTime);
    **detachInterrupt(0);
    **return (numPulses < 3) ? 0 : (1000000.0 * (float)(numPulses - 2))/(float)(lastPulseTime - firstPulseTime);
    }
    
    
    void loop()
    {
    
    **
    **float freq = readFrequency(100);
    ****if ( freq > 2000)
    {
    **digitalWrite (ledPin, HIGH);
    **digitalWrite (relay1Pin, LOW);
    **digitalWrite (relay2Pin, LOW);
    **digitalWrite (relay3Pin, LOW);
    **digitalWrite (relay4Pin, LOW);
    **
    **Serial.print("ChargePump Active. Current Frequency: ");
    **Serial.println(freq);
    }
    else
    {
    **digitalWrite (ledPin, LOW);
    **digitalWrite (relay1Pin, HIGH);
    **digitalWrite (relay2Pin, HIGH);
    **digitalWrite (relay3Pin, HIGH);
    **digitalWrite (relay4Pin, HIGH);
    **Serial.print("ChargePump Inactive. Current Frequency: ");
    **Serial.println(freq);
    }
    
    **delay(100);
    }
    Q: How many tools does it take before a simple task becomes a project?
    A: Just one. I'm the Tool that turns a simple task in to a project.

Similar Threads

  1. Charge Pump
    By cadmonkey in forum LinuxCNC (formerly EMC2)
    Replies: 8
    Last Post: 04-06-2010, 07:19 AM
  2. Charge pump - do I need this on?
    By zeeway in forum Gecko Drives
    Replies: 17
    Last Post: 01-05-2010, 07:40 AM
  3. charge pump
    By michaelf in forum Benchtop Machines
    Replies: 23
    Last Post: 10-25-2009, 11:55 PM
  4. charge pump
    By eloid in forum DIY CNC Router Table Machines
    Replies: 3
    Last Post: 01-25-2009, 04:14 PM
  5. Charge Pump ???
    By jack55 in forum CNC Machine Related Electronics
    Replies: 6
    Last Post: 04-21-2007, 08:59 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •