Freq reader Help!!

Hey guys so Im making a frequency reader to display my Freq on my tig welder. Well this is short and simple I have A Inland mini pro(Arduino ProMini Knock Off) this program I wrote works great! but thats my test board for Breadboards. I have 6 Adafruit Trinket Minis and 4 Diavolino Boards all 16MHZ. I cant get this same prog to work on any besides the ProMini? So far what I have narrowed it down to is the reading from interrupt input.

If I Serial.print() it Reads perfect!!! right on the money with the ProMini Highest 600Hz and reads 599-600. The Diavolino Reads all over the place at 600 its like 170ish and down at 80 its like 20ish??? I cant Serial.print() with the Adafruits but im sure same problem. Now my input, for testing, Is an output from one of the 3 different boards I have... This Program is fine on any.

int Out = 5;
int Led = 13;
void setup()
{
  pinMode(Out, OUTPUT);
  pinMode(Led, OUTPUT);
}

void loop()
{
  digitalWrite(Led,HIGH);
  digitalWrite(Out, HIGH);
  delayMicroseconds(826); // Approximately 599.6Hz 
  digitalWrite(Out, LOW);
  delayMicroseconds(826);
}

This next code for my reader. I am displaying to the 3 Digit 7seg that's on the machine which is an amp meter. I wanted to not have to make a second display and use the one that's in it and just switch between amperage and freq. Now I just have my out running through a 3.3M resistor(So high due to 176ma makes it shoot up to 746 so with the 3.3M now 4.97V tops out a 600. gives me much more room to work with) I mapped out the 0-600Hz to 0-255. you'll see its a tiny bit off as I wanted to be as accurate as possible and noticed the amp display doesn't want a perfectly liner up as it rises in number so I went with what worked the best. displays 600@600Hz and 55@54Hz so pretty darn cool if you ask me... way easier than setting up a whole LCD or 7Segment for sure.

 int Hz = 0;   
 int rpm = 0;
 int Out = 5;    // Output
 unsigned int HZ = 0;
 unsigned int HzOut = 0;
 unsigned long lastmillis = 0;
 

 

 void setup(){{ 
   Serial.begin(9600);
 pinMode(Out, OUTPUT);
 attachInterrupt(0, Freq_Reader, FALLING);
 }}

 void loop(){

 if (millis() - lastmillis == 1000){ //Uptade every one second, equals to frecuency (Hz).
 detachInterrupt(0);//Disable interrupt when calculating
 HZ = Hz;
 int HzOut = map(HZ, 4.5, 613, 0, 260);
 analogWrite(Out, HzOut);
 Serial.println(Hz);
 Hz = 0; // Restart counter
 lastmillis = millis(); // Uptade millis
 attachInterrupt(0, Freq_Reader, FALLING); //enable interrupt
  }
 } 
 void Freq_Reader(){
  Hz++;
 }

Any thoughts Im so lost why all those interrupts cant read the signal correctly but that ProMini can....
Thanks

Rather than use detachInterrupt() you should try noInterrupts() followed immediately after the line
HX = hz;
by interrupts(); That way the interrupts are suspended for the shortest possible time.

Then you don’t need attachInterrupt() within loop().

…R

Hi, I spotted a couple of things...

 int HzOut = map(HZ, 4.5, 613, 0, 260);
 analogWrite(Out, HzOut);

The highest value analogWrite() can take is 255. That map() function could go up to 260. I think 256 will be treated as zero, 257 as 1 etc.

Also the 4.5 value will either be rounded to 4 or 5, or the other values will get converted to float and thd result converted back to int at the end, which may slow the sketch down, just when interrupts are disabled.

Paul

I've tried the map(HZ, 0,600,0,255) all over the place I played around with all four numbers like crazy... But that's not the problem this works!!! Just not on two other boards.. So the 612,0,260 doesn't matter since it works like that on the other.

But the noInterrupt() this is a thought.... I'm not sure how that'll work if I never have to attach the interrupt??? Can you explain this further? Or maybe copy my code and edit in what u mean...

But on that interrupt thought of taking to long. Why would that matter if I reset the lastMillis right before I attach it. So no matter how long it takes to calculate, it shouldn't affect my count at all since the microsecond after it resets last millis it starts the interrupt count. Right?

You should generally attach the interrupt handler once at the start of the program.

Critical parts of the code should be protected by
No interrupts
...
Interrupts

Your 260 mapping may 'work', but you're building in potential unreliability without either reducing the range or adding a clamp.

nissan20det:
Can you explain this further?

How about reading the Reference section.

All my suggested code does is stop the interrupts while you read the value and then let them continue.

Or maybe copy my code and edit in what u mean...

I did not think it was so complicated to require that.
Instead of this

 if (millis() - lastmillis == 1000){ //Uptade every one second, equals to frecuency (Hz).
 detachInterrupt(0);//Disable interrupt when calculating
 HZ = Hz;

do this

 if (millis() - lastmillis == 1000){ //Uptade every one second, equals to frecuency (Hz).
 noInterrupts();//Disable interrupt when reading value
 HZ = Hz;
interrupts();

and then remove the line from loop() that contains attachInterrupt()

Normally, attachInterrupt() should only be in setup();

...R

Okay I get it that makes since I thought you ment never say attach it at all... I was wound earring how it would ever begin then....

But the 260 doesn't act like you think ..... At 255 I was getting 600-@600hz but lower was like 76@82hz when I adjusted it to 612 and 260 made it within 1 hz accuracy. Now your saying 612,260 is the same as 612,005? If so how is my voltages out above 4v? 5v/255=19.60784mv * 005 is 98.039mv. So are you sure the 255 is just max potential out and anything higher is still the same? That would make more since why I'm getting above a 4v sig out at 600hz..

So I guess the fix was the 2,612 and the 0,260 is just acting like 0,255. Okay... So I'm still lost on what my problem is here I figure all these Arduino type boards that are 16 MHz act the same??? I'll try the no interrupt() thing... I figure all atmel processors would read their interrupts the same...

Any other thoughts at all ..... Cuz it's not the 260 thing I tried a bunch of numbers.

Are you sure the trinket is running at 16MHz? It says here that:

Internal oscillator runs at 8MHz, but can be doubled in software for 16MHz

I don't know why this would cause your odd readings, because the trinket arduino core should force millis() to work correctly at 8MHz. Don't know how that is maintained if running at 16MHz...

Like my suggestions before, I don't know what is causing your problems, just doing my best to suggest things for you to check. Your readings with the other boards seem to be around 25% of the expected reading.

nissan20det:
But the 260 doesn't act like you think ..... At 255 I was getting 600-@600hz but lower was like 76@82hz when I adjusted it to 612 and 260 made it within 1 hz accuracy. Now your saying 612,260 is the same as 612,005? If so how is my voltages out above 4v? 5v/255=19.60784mv * 005 is 98.039mv. So are you sure the 255 is just max potential out and anything higher is still the same? That would make more since why I'm getting above a 4v sig out at 600hz..

I have no idea what all that means. Especially because I never had any thoughts about how the 260 acts.

Who is the "you" that you are referring to ?
What is the 260 that you are referring to ?

...R

nissan20det:
So I'm still lost on what my problem is here I figure all these Arduino type boards that are 16 MHz act the same???

nissan20det:
Now I just have my out running through a 3.3M resistor(So high due to 176ma makes it shoot up to 746 so with the 3.3M now 4.97V tops out a 600. gives me much more room to work with)

The 3.3M impedance is far too high to get accurate and reliable readings, especially over a frequency range. Just the slightest variance in input capacitance or how clean the PCB trace and input terminal is, or susceptibility to noise or other signals in close proximity all would cause changes in signal quality and timing.

Could you post a diagram of your circuit (especially the interface to your interrupt)?

From what I could make of it, you have an output generating roughly 600Hz at 50% duty cycle (0-5V) connected in series with a 3.3M resistor. The other end of this resistor would be connected to your interrupt pin.

NONONONONo Sorry I must have confused you guys!!
So Me refurring to the 255 is in reference to voltage out. I thought that is how these boards broke up voltage. That 255 would be 5V 127.5 would be 2.5V and so on… Now I am taking me welders frequency out from the controller board. Then sending that into A CD40106 Schmitt Trigger (To have a nice square wave). Then strait into the Arduinos Interrupt IN. Then I am Trying to convert the 0-600Hz to a liner voltage out. My display is the in welder 3 digit 7 segment amperemeter. The easiest way I saw was Just use the Input.I tried at first and at 76mv I got 787 on the display so that would make my 0-600 in voltage 0-60mv ish… That is way to small to work with so I noticed As I increased resistance between the arduino and the display I was able to get lower display numbers at higher voltages. I ended up with a 3.3M resistor, this will now display 600 when the arduino is at 255 PWM out.

Now im not sure any of that is my problem I currently have it in the welder working fantastically with the Mini Pro. just have two switches one that changes the display input from machine(amps) or arduino (freq) and the other is the A/C_D/C selection I have changing the machine as well the input Freq (either ac or dc) into arduinos INT0…o
i just really wanna use one of the other boards I have.

Also the Trinket Mini is 16 MHZ you just need this in your code… and so far the internal clock I have only seen affect anything when I use one to make a pulsed square wave.

delayMicroseconds(826); // Approximately 599.6Hz @ 16MHz
delayMicroseconds(413); // About 600Hz @ 8MHz

#include <avr/power.h>

if (F_CPU == 16000000) clock_prescale_set(clock_div_1);

I’m completely lost. But maybe that does not matter.

…R

I'll put is as simple as possible....

I have a 3 digit 7 segment display(Amperemeter). Screwing around I realized the display will change is reading if you very the voltage.( 5-millivolt will display 200, 76-millivolt displays 787) So as I rise in voltage I rise in number(ON Display) If I add a 3.3M resistor in between my adjustable voltage source and the displays HI input(it has a 5V, 0V, HI, and LO) input then this allows me to display 600 at exactly 5Volts and 0 at 0.

I'm taking a square wave pulse, Sending that to the Arduino wanting to to count Pulses Per Second. I successfully have a good count on the Pro Mini Arduino. I am converting that Hz Count to fluctuate voltage. So If the Arduino reads 600Hz I want a PWM pin to put out 5Volts, 300Hz makes Pin Out = 2.472V, 0Hz = 0V.

Please if your still lost let me know what you don't understand

Ohh! PaulRB

By the way Yes you are correct on the 255 thing you where just a tad off. I guess I was just under the nose of it…I tested it and 255-261 there is no difference with PWM voltage out(Adafruit stayed at 4.87 and the Mini Pro/Diavolino stayed at 5V) it will start to chatter at 262 and bounce from 12Mv to 5V and 264 resets at 10Mv and starts over…

Okay so I did figure it out!! I would still love your guys’ input if you understand me now and as well how this fixed it.

first code is the beginning of the one that didnt work on the adafruit or diovolino the second code works for the adafruit, and diavolino as well now. I changed the wording before Setup()

int Hz = 0;   
 int rpm = 0;
 int Out = 5;    // Output
 unsigned int HZ = 0;
 unsigned int HzOut = 0;
 unsigned long lastmillis = 0;
 

 

 void setup(){{
   Serial.begin(9600);
 pinMode(Out, OUTPUT);
 attachInterrupt(0, Freq_Reader, FALLING);
 #include <avr/power.h>   // <-----Just for Adafruit to work at 16MHz
 int Hz = 0;
 int Out = PB0;
 unsigned HZ;                // <---- these where in this style---> unsigned int Hz = 0;
 unsigned Rpm;
 unsigned HZOut;

 void Freq_Reader(){      // <-----Moved this from bottom to here(dont think it did anything)
  Hz++;
 }
 unsigned long lastmillis = 0;

 void setup(){
   if (F_CPU == 16000000) clock_prescale_set(clock_div_1);   //<------ just for adafruit
 attachInterrupt(0, Freq_Reader, FALLING);
 
 }

 void loop(){{

 if (millis() - lastmillis == 1000){                                //Updataed every one second

 detachInterrupt(0);                                              //Disable interrupt when calculating

 Rpm = Hz * 60;                                                   // Convert frecuency to RPM, <--- this is so I can use this code for an RPM gauge for my Mill too 

 HZ = Hz;
 int HzOut = map(HZ, 4, 612, 0, 255);
 analogWrite(Out, HzOut);

 Hz = 0;                                                               // Restart the RPM counter
 lastmillis = millis();                                                // Uptade lasmillis
 attachInterrupt(0, Freq_Reader, FALLING);               //enable interrupt
  }}
 }

So all in all I don’t get why that made it work I guess the Mini Pro wasn’t as Picky?

nissan20det:
If I add a 3.3M resistor in between my adjustable voltage source and the displays HI input(it has a 5V, 0V, HI, and LO) input then this allows me to display 600 at exactly 5Volts and 0 at 0.

I'm assuming that it works fine without the resistor but it displays the wrong numbers. If so, why not omit the resistor and just use some simple maths to adjust the numbers to the range you want ?

then this allows me to display 600 at exactly 5Volts and 0 at 0.

...SNIP... So If the Arduino reads 600Hz I want a PWM pin to put out 5Volts, 300Hz makes Pin Out = 2.472V, 0Hz = 0V.

Are these the same "600s" or are there two completely separate values that both happen to be 600 just by coincidence.

If they are the same, then I have no idea why you call it a frequency since it is derived from a voltage.
If they are different then you need to explain the system more clearly.

...R

Robin2:
I have no idea why you call it a frequency since it is derived from a voltage.
If they are different then you need to explain the system more clearly.

I get it. The OP has an existing display on the welder which currently displays only the current. He wants that display to show either the current (as now) or the "frequency" (don't know what this frequency is, I don't know much about welding). The display has an analog input that drives it. The OP is attempting to display the frequency in Hz on this display by measuring the frequency with the Arduino and converting it to an analog voltage, and calibrating this voltage so that a frequency of 600Hz is displayed as "600" on the display.

But I'm not surprised you are confused and uncertain, Robin! The OP's pattern of speech, punctuation style and fondness for rambling sentences mean I have been reading everything 3 times over and I am still not sure I understand 100% of what he is trying to say.

In this manual, there is a section on the display that can show the TIG Pulser frequency.

Can you provide a link to the operator's manual of your TIG welder, or provide the model number??
What does the frequency that you wish to display represent?? Are you generating 600 Hz so you can display 60.0 Hz line frequency??

Without knowing any of this, I'm sure a 3MΩ series resistor is an inappropriate method of signal calibration. Is this resistor also meant to protect the electronics from high voltage spikes on the signal? An optocoupler comes to mind, but that brings me back to the above questions. Oh well.

My welder(Luxor Tig 200P) eBay Chinese welder you wont find anything on it other than it for sale. It took me 9 months just to get the schematic. Now this welder stock has a fixed 60Hz A/C frequency and an Adjustable 0-300Hz D/C Pulse frequency(Pulses from high to low current). I originally tried so hard to get the schematic because the D/C frequency was not going up to 300Hz like the Machine said it should. (Highest D/C pulse was 174Hz). As well I wanted to be able to adjust A/C frequency(This helps for arc wander and arc size).

I did that and now my A/C frequency is adjustable from 50Hz-250Hz. I also adjusted the D/C section, that now ranges from .5Hz-600Hz. Paul is right I want the stock display to be able to switch from showing current to frequency. It needs an analog IN. Now yes, I could scrap the 3M resistor but my analog voltage would then have to range from 20millivolt- 160millivolt to display 0-600. With the analog voltage so low like that the display bounces all over the place. For instance, if I calibrate the Arduino to map HZ 0, 600 to 20mv, 160mv the display will jump between 280 and 315 pretty fast if I am reading 300Hz.

So not only does the 3M resistor allow for my analog range to be quite a bit larger(0-5V), It as well gets rid of that crazy bounce in the display. So the overall purpose of the resistor is to steady the display reading, and allow my analog out to have a larger range. 20mv-5v is a lot larger than 20-160mv.

But all in all none of that really matters as I have it working in the welder fantastically! So as much as you guys say that 3.3M resistor is not needed then please please tell me a more simple way of doing this.. and I'm not sure how much easier you can get then soldering a resistor inline..... remember my display now fluctuates one number.. maybe... So that's within 1 Hz accuracy. As well I get absolutely no jitter in the display from outside interference.

All I want to know is how did changing the format from-- "unsigned int Hz = 0;" to "unsigned Hz;" work?

nissan20det:
Now yes, I could scrap the 3M resistor but my analog voltage would then have to range from 20millivolt- 160millivolt to display 0-600. With the analog voltage so low like that the display bounces all over the place. For instance, if I calibrate the Arduino to map HZ 0, 600 to 20mv, 160mv the display will jump between 280 and 315 pretty fast if I am reading 300Hz.

I think I was following the description very nicely until we got to this bit which suddenly starts mixing volts and Hertz again.

...R

Geez man.... Every time I refer to a number with no unit of measurement (0-600)that is referring to what is shown on the display... If I have the unit "Hz" after any number I am referring to the Freq I am reading out of the welder. Finally any Voltages I am talking about is the converted Freq to analog coming out of the Arduino that's needed to make the display work.