wvmarle:
Impressive! You really go it the hard way. Direct register calls are not necessary in this application; I rarely use them myself, only when really needed.
You could also use the following command for the interrupt:
attachInterrupt(digitalPinToInterrupt(sensor1), FALLING);
Much easier than those register calls.
But there are other things you go terribly wrong: you're using print statements in your ISR. That's bad. Nowadays this does work, but Serial requires interrupts, which are disabled when you're inside an ISR. Furthermore those print statements don't do anything useful: they just show the pin number of the analog pin.
You probably want to do an analogRead() on those pins to get the current value - a function which itself may or may not work in an ISR, I don't know how it's implemented. The ADC itself also uses interrupts, to signal a reading is ready.
Polling the pins will be fast enough for your coin acceptor. No need for interrupts or direct port manipulation.
Finally, I'm sure you can come up with better names than "analog_sensor1" for the pins.
Thank you for pointing out my mistakes in coding. There are still many unintentional errors that I have surely made without noticing and I will come up with better names for those variables. I have also applied the interrupt command that you mentioned but I just wanted to learn a little bit about using direct port manipulation and direct register call. I guess it is not necessary for this application since it will make it harder to read and debug the codes.
By the way, when you mentioned about "Polling the pins", is it an electronic terminology? What does it mean exactly if you would not mind me asking because I did not fully understand the term.
david_2018:
Direct port instructions are not needed in setup, and make the code harder to read. It is understandable to use direct port manipulation in the interrupt service routines, because it is generally better to have an ISR be as fast as possible, but then you completely negate the savings by doing an analog read and a print. Much better to set a flag and do those in the main code.
I don't really see how generating pulses and counting them would play any part. Seems like a lot of extra code to set up a pulse generator, then more code to count pulses. I would think the micros() function would be fast enough, but if not then one of the internal counters could be used.
You would probably get higher accuracy if you used the time interval between the two sensors to determine the velocity of the coin, and the time it takes to pass the 2nd sensor to do the width measurement. Don't assume the coin will always be traveling at the same velocity, unless you have a mechanism to guarantee that. The ISR for the first sensor could record the time the coin reaches the sensor, then the ISR for the 2nd sensor could record the time the coin reaches the sensor and the time it leaves, and set a flag letting the main code know it had completed detecting a coin. As others have pointed out, I'm not sure if you even need the speed of an ISR, the times intervals involved are not that short, but it depends on what else you will be doing in the code.
Thank you kindly for your suggestion and opinions on generating pulses. I will try setting up a flag variable to keep track of the process and micros() function to better the timing accuracy. I am having almost the same approach to the solution as you suggested in the last paragraph.
Also, would the data type of the variable "flag" be volatile or uint8_t and that "flag" could also help with resetting the millis() function because I do not really want the millis() function to keep going and taking up memories if that is how I understand the function works correctly?