Store and Forward Telephone Rotary Dial Pulses

I would like to detect rotary dial pulses using an opto, and store them. After a 4 second timeout occurs (end of dialing), forward the stored pulses to a relay. The incoming detected pulses would be 7pps to 23pps, with an interdigit break time of about 750ms. The outgoing pulses would be 10pps, with a break time of 750ms.

I want about 6 I/O. So it would need to be able to do the same function for 6 inputs and 6 outputs. Each input would always drive the associated output, 1 for 1.

I am looking for suggestions for the hardware, and some ideas for the coding.

Thanks

How noisy is the signal?

7..23 pps can easily be done by arduino.

First receive pulses and store them into an array until an interdigit break detected.
Then send out the pulses from the array to an output pin.

// not tested/ not working code to get started

int pulses[100];
int idx = 0; // index for the array;

const int inpin = 5;
const int outpin = 6;
void setup()
{
  Serial.begin(115200);
  Serial.println("debugging output: ");
  
  pinMode(inpin, INPUT);  // can be any pin
  pinMode(outpin, OUTPUT); // can be any pin
}

void loop()
{
  waitForPulses();
  ReceivePulsesInArray();
  SendPulsesFromArray()
}

void WaitForPulses()
{
   while( digitalRead(inpin) == LOW);
   Serial.print(millis());
   Serial.println("\tHIGH pulse detected");
}

void  ReceivePulsesInArray()
{
  unsigned long lastPulse = millis();
  while (millis - lastPulse < 750)
  {
     // record pulses into array
    pulses[idx] = ??
     idx++;
  }
}

void SendPulsesFromArray()
{
  // assume 50% duty cycle in the outgoing pulse
  for (int i =0; i< idx; i++) 
  {
    // write the recorded pulse
  }
  idx = 0; // reset index
}

Rob,

I expect the pulses to be pretty clean. They would be locally generated, so there should be very little distortion.

What version of an Arduino would work best for this?

Don't know how you define best, but a mainstream UNO should be able to do this wthout problem.

I expect it can even run on a tiny45 or tiny85.

I expect the pulses to be pretty clean. They would be locally generated,

They could still have a lot of bounce though, what's generating the pulses?


Rob

while (millis - lastPulse < 750)

this gives an error

i cant find out why

Because "millis" is a function pointer, so the comparison doesn't make sense.

oooooohh

so if i were ti find out what millis has to be this would work?

If you called millis, it should work.

The pulses would be generated by a telephone dial or a relay contact in the FXO interface in a Cisco router.
Thinking about it, It would probably need about a 10 ms de-bounce routine.

robot797:
while (millis - lastPulse < 750)

this gives an error

i cant find out why

Try: while (millis() - lastPulse < 750)

Time to think outside of the box I think. Why not forget all this timing stuff and just make a 4-second delay line.

Have a circular buffer, let's say 4000 bytes in size, every mS you read up to 8 input pins and put the value in the head of the buffer, at the same time you read the value from the tail of the buffer and write that to 8 output pins.

Job done, no debouncing, no complicated timing, just read/write/wait/read/write/wait...you don't care about pulse widths, end of value spaces, nothing. It's just a delay line, what is presented on the inputs is echoed on the outputs 4 seconds later.

You can change the delay time simply by changing the buffer size and not changing the frequency of reading. OTOH if 1mS is more resolution than you need make it say 10mS and reduce the buffer to 400 bytes.

The only catch is that you may need a Mega or Teensy etc to hold the array. Teensys are $20.


Rob

I need the 7pps-23pps input timing range to be stored and sent to the outputs at 10pps. If the input timing was retained, the output timing would match the incoming timing.

OK, that's different, carry on :slight_smile:


Rob

n you need make it say 10mS and reduce the buffer to 400 bytes.

Then an UNO would be sufficient

John-S:
I am looking for suggestions for the hardware, and some ideas for the coding.

I don't know anything about the electrical characteristics of your input and output signals, but I guess that you will probably need some input signal conditioning on the input and some drivers on the output - the Arduino will only accept a 5V signal and will only generate a 5V output at up to about 20mA.

For the software I would implement a state machine which keeps track of whether a given input in in a dialing sequence or a replay sequence, and keeps track of the buffered pulses. Debounce the inputs in software before feeding to the state machine. Hold the state machine states, input and output pin numbers in arrays and process them all using common code in a loop. If you can cope with object oriented design, this state machine would be a good candidate for implementing as a class, with an instance for each channel and all the instances held in an array.