[SOLVED] Open collector with only 2 wire ?


I own a digital electric energy meter: PRO1D V10.122

I want to count pulses from it with my arduino MEGA 2560.

I written some code and test it with a push button switch because I though that the output from the energy meter was a kind of switch. But I’m wrong, it’s an open collector. The documentation said that I have to connect the collector to 5-27V DC. (see the extract of the documentation in attachement)

But I’m figure how I can do it ? My level in electronic is very close to zero, so if you can give me a drawing as detailed as possible maybe I could pass this step ?


Put a 10K resistor from pin 20 to +5V. Connect pin 21 to Gnd. Pin 20 will read 5V when no current flows thru the LED , and close to 0V when the LED is turned on.

Thanks for your answer,

If I understand you right, the wiring should look like this:

Arduino MEGA                             PRO1D V10.122

     +5v <------------->10khom <-----------------> 20
   pin #2 <---------------------------------------> 20

   GND <-------------------------------------------> 21

Can I link GND, to any of GND pins I have on the arduino board ?

Yes that is right. Any ground will do they are all the same.

Thank you it's resolved. :D


i am having difficulties on my project electric submeter using gsm, do you have any codes on this arduino?

Here under the code on the arduino side.

Sorry, comments are in french. Basically the arduino is incrementing a variable on each pulse. From the pc connected with usb cable, I send a message "a" to arduino via serial line. When it receive this message, it sent back the counter status. Everything is based on events (contact on pin, serial port communication)

I hope it could help you

ComptageImpulsionCompteurEnergie 0.1 (08/09/13)

Compte les implusions issues d'un contact sec sur un compteur d'energie 
et l'envoie sur le port serie. Un application cote PC relie au port serie
ecoute sur le port serie et stocke les valeur dans une base de donnee RRD
voir RRDtool: http://oss.oetiker.ch/rrdtool/

/* Initiallisation du compteur d'impulsion
cette variable doit etre declaree "volatile" pour pouvoir la manipuler
a l'interieur d'un fonction appelee par une interruption */
volatile int impulsions=0;
/* Debounce: il existe un phenomène de rebond lorsque appuis sur un bouton poussoir, dans le cas
du contact sec du compteur d'energie je ne sais pas si cela est le cas, mais je prefere le gerer
au cas ou. Deplus cela me permet de debuguer en faisant contact a la main*/
volatile int debounceOld=0;
volatile int debounceNew=0;

void setup()   { 

/* L'entrée digitale 2 correspond a l'interruption 0
INPUT_PULLUP permet d'activer la resistance PULLUP interne ce qui evite que l'etat
de l'entre ne soit pas stable*/
pinMode(2, INPUT_PULLUP);

// Initialisation du debit du port serie

// Lance l'execution de la fonction gestionINT0 lorsque il detecte un front montant sur l'entre 2
attachInterrupt(0, gestionINT0, RISING);


void loop(){ 
  /* Ici je ne fait rien:
  - le comptage est effectué par l'interruption
  - l'envoie par port serie par la fonctione serial évent à la demande du script sur le PC

/* Fonction appellee par l'interuption 0 
les variables utilises dans cette fonction doivent etre declarees: volatile
les fontions delay ne sont pas utilisables dans cette fonction
void gestionINT0() {
  /* Une valeur de 100ms est suffisante pour eliminer les rebons (si on manipule avec attention) un 
  contact manuel et ne risque pas de 'sauter' des impulsions du compteur: pour un compteur 
  avec 0,5kWh/ impulsion cela ferait 5kWh/s ce qui est enorme */
  if (debounceNew-debounceOld>100) {

 SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.

 Ici j'envoie l'etat du compteur quand je reçoi l'ordre 'a'
void serialEvent() {
    // get the byte:
    if ((char)Serial.read() == 'a') {