High speed production counting

That’s why I suggested reflective...:slight_smile:

Some ideas: https://literature.rockwellautomation.com/idc/groups/literature/documents/br/sensor-br001_-en-p.pdf?event-category=Brochure&event-action=Download&event-label=SENSOR_FamilyBrochure_EN

Here i attached my code. Please give me some suggestions.

sketch_feb04a.ino (20.5 KB)

Just a hint...
Many helpers can't open INO files when they're on iPads or other mobile devices.
If it's too large, suggest attaching as a .c or .txt file. or break it into smalller logical parts ...

    sketch_feb04_part1.c
    sketch_feb04_part2.c
    sketch_feb04_part3.c

etc...

One thing I noticed immediaely...
There are several if-else-if bocks, that could be converted to switch() case blocks with a little more thought, which would make the code cleaner, and easier to follow.
In fact the days of the week blocks, could be compressed to one line - using a char array of day names, and converting 'day2' into an index into that array.
[tt](day2 = (day2 /10) -1;  // gives a range of 0 Sunday to 6 Saturday)[/tt]
That DOW could be put into a function, as it's used multiple times throughout the program

Have you verified the code will count reliably if all it has to do is count? That is, with all the recordkeeping/day of week stuff stripped out?

void COUNT()
{
  count1 = EEPROMReadInt(address);            //.......count interrupt
  count1 = count1 + 1;
  EEPROMWriteInt(address, count1);
  flag = false;
}

250 units/sec = 15,000 units/min = 900,000 units/hr = 7.2M units/8hr shift.

EEPROM is guaranteed for 100,000 writes.

Time to write a byte to EEPROM is ~5ms. 250 units/sec = 4ms between units. Will there be enough time to write a count before the next interrupt comes in?

It is 250 units per min so it is 4 units per seconds.

So i think it has sufficient time to write on EEPROM before the next pulse come.

The count should be remain same even the power is fail, so i need to store in EEPROM all the time it get updated.

Have you tried simulating the input? Some kind of bench top setup that generates pulses at a known rate so you can test without using the actual bottle line.

I've used a Nano to do this.

John.

Whenever your code accesses a variable (and in your case an eeprom location) that is also used in an interrupt service routine, interrupts need to be disabled to avoid an interrupt from occurring during the access. The arduino can only access memory one byte at a time, so an interrupt can occur between accessing the two bytes of a 16-bit integer, allowing the interrupt service routine to change the variable in mid-instruction.

Instead of constantly reading and writing to eeprom, use something to detect loss of power, and use a large capacitor or small battery to give you enough time to store the current information whenever you lose power. DS3231 boards also commonly have a serial eeprom (such as an AT24C32) that allows more writes to memory than the internal eeprom.

Getting the day of the week as text and using comparisons is rather cumbersome, you can get the current time from the rtc (in the form of a Time type variable), and get a numeric value form that for the day of the week, from 1 for Monday through 7 for Sunday, although the weekdays in all capital letters are defined for you as the appropriate number, in case you want to do something like:

  Time t = rtc.getTime();

  if (t.dow == MONDAY) Serial.println("Monday");

  //use day of the week in a switch..case statement
  switch (t.dow) {
    case MONDAY:
      Serial.println("Today is Monday");
      break;
    case TUESDAY:
      Serial.println("Today is Tuesday");
      break;
  }

.getDOWstr(), .getDateStr(), and .getTimeStr() return char pointers ( char* ), no need to define a String variable to hold them, just save the char* to a variable and use that to access the data. The String type should be avoided on an arduino anyway, it can lead to memory corruption, particularly if the sketch is run for an extended amount of time.

If you need to save date and time to eeprom, using unix time format is much more efficient.

Thank you guys for your suggestions, i will definitely work on them.

I have found the solution of my problem. Actually i am using software serial for nextion, and pinchange interrupt also. So the conflict is going on during communication.

Now i am using hardware interrupt pin 2, for input pulses and the counting is perfect.

Now i have to deal with memory functions, to avoid too much writing on EEPROM.

Which arduino are you using? I see from the code it has at least two hardware serial ports.

I used the pulseln() function on my car speedometer. Very easy coding.

Works fine up to 100 kph.

100 kph means 14 revolutions of the wheel per second, ie,14 pulses per second to catch. Enough time to compute total revs, speed and distance travelled.

Using a Nano.

John.

i am using arduino mega 2650 for my project