Last Updated: 09/08/2021
Project 1 - Arduino NAMUR sensor control
Projects >> Project 1 - Arduino NAMUR sensor control
Arduino NAMUR sensor control
As part of a bigger project to rebuild a bag filling machine for my son, I needed to use an Arduino to read the pulses generated by a NAMUR standard Inductive slot sensor.
The sensor I needed to control was a SJ3,5-N made by PEPPERL +FUCHS. This type of sensor runs on 8.2v DC and is made to a very high safety standard enabling it to be used in hazardous situations. It's an impressive sensor but not something that the average Arduino user comes across so I had some initial struggles getting the sensor to work.
In my application I have spinning disc with what looks to be some kind of metallic coating on it but in distinct blocks. These blocks are picked up by the sensor as it spins and unlike a photo interrupter this sensor has the advantage in my application of being able to work in a very dusty environment with no loss in performance.
The sensor is able to read up to 3000Hz but has an unusual way that it is connected. The sensor only has 2 wires so at first I assumed it would be an Open/Closed circuit. However, these sensors work in an unusual way in that instead of being open and closed, the generate a sine wave as the blocks come in and out of range of the sensor, but the circuit never truly closes. This seems to be a safety feature in that if the circuit is closed the sensor or circuit has failed. Well beyond my understanding but I assume in a hazardous environment you would want to know when something had failed.
In my project I needed to be able to count a number of steps and then stop the machine. As the Arduino would also have to be doing various other tasks such as controlling a touch screen, a set of digital scales and operating an electric brake and clutch I decided that the best route would be to use an interrupt as a pulse counter.
Initial attempts looked promising but for some reason the circuit I was using combined with an Arduino Mega 2560 seemed to stop working above 300 pulses per second and I needed around 600 so decided my circuit should be able to handle at least 1000 pulses per second to be safe.
As I was unsure of why my previous system failed I decided to test everything from basics so my first test was to use 2 x Arduino Uno's. One to generate a signal and the other to use an interrupt to pick it up. The goal was to make sure 1000 interrupts per second was feasable.
Example 1: interruptGeneratorv1.ino
Click to Download code:interruptGeneratorv1.ino
To find the maximum speed the Arduino could handle interrupts I first needed a simple sketch to generate signals at high speed for the interruot to pick up.
Simple sketch that turn pin 13 HIGH, delays a short time and send the pin LOW. It's basically the old blink sketch but running much faster.
As my testing got faster and faster I switched from delay() to
delayMicroseconds
().
/* Just switched pin 13 HIGH and LOW
*
*
*/
int timeDelay = 5;
void setup() {
Serial.begin(9600);
Serial.println("interruptGeneratorv1...");
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
//delay(timeDelay);
delayMicroseconds(timeDelay);
digitalWrite(13, LOW);
//delay(timeDelay);
delayMicroseconds(timeDelay);
}
Example 2: maxspeedUnov1.ino
Click to Download code:maxspeedUnov1.ino
This script was used to pick up the signal from interruptGeneratorv1.ino above.
My initial test was done by connecting the GND's betwen the boards and connecting PIN 13 to PIN 2 on the receiving Arduino.
This worked well and I tested to a limit of delay(1) that proved I could get 1000 pulses per second.
/* Test to see how fast UNO can receive interrupts
* Due to buckitcraft issues
*
*/
long InterruptCounter = 0;
unsigned long intTimer;
const int InterruptPin = 2;
void CountInterrupts(){
InterruptCounter++;
//Serial.println(InterruptCounter);
}
void setup() {
Serial.begin(9600);
Serial.println("maxspeedUnov1...");
//interrupt for sensor
attachInterrupt(digitalPinToInterrupt(InterruptPin), CountInterrupts, CHANGE);
}
void loop() {
if(millis() > intTimer){
intTimer = millis() + 1000;
Serial.println(InterruptCounter);
}
}
Example 3: Creating a circuit
Once the scripts above had proved I could get the speeds I wanted I then needed to build a circuit capable of working with the NAMUR sensor. The simplist circuit diagram I had got hold of to interface with the sensor is shown below. The circuit works by triggering a transistor as the voltage on the sine wave increases. I'm not an electronics, expert but I was told that the sensor had a very smooth sine wave so it would trigger at excactly the same point in the wave each time giving very accurate timings between pulses..
The diagram I got hold of did not have a transistor listed and had no value for the capacitor so I just used what I had in my parts box and used a capacitor that said 104 on it and a 2N2222A transistor, as I've said I'm no electronics expert, but decided to risk blowing up cheap stuff first.
The next stage was to add a few extra components and connect in the Arduinos. Although the Arduino sending the signal was just going from HIGH to LOW and back I was hoping that the circuit would still work. I added a red and green LED, one on the input side and the other on the output. I added these to get a visual indication at lower speed that everything was working correctly. The final circuit is shown below. The LED on the input side will need to be removed for the production version as the supply will be 8.2v so more than the LED can handle.
I then slowly decreased the delay() until it got to 1 millisecond and so swapped to using
delayMicroseconds() and kept reducing the delay interval until the recieved values from the interrupt started to fail. The best stable values I could get was with a 5 microsecond delay that produced a consistent value of over 138,000 pulses per second on the interrupt pin and was stable at that rate for over an hour with nothing getting warm before I turned it off.
Although I managed to get a sustained rate of over 138,000 interrupts pr second the uable figure would be much less as the only other code running in the test script is a Serial.println() once a second. As my project has Serial1 and Serial2 events running as well as other code I would expect the usuable value to be much less, but much greater than the 1000 I need.
06/08/2021 After the circuit was installed onto a prototype shield and run on an Arduino Mega 2560 it managed to sustain 260000 pulses per second. I must confess I was impressed. When this was tested within the main code it still managed to sustain 245000.
Installation
Once installed in the machine the new circuit performed faultlessly with superb accuracy. The result is a machine that has been repurposed and gives a bag filling accuracy of within 1.2% without ever going under weight, that should get even better after a bit of fine tuning.
Additional Resource Links
Comments
This site has been designed to be child friendly, this means that comments cannot be added to videos or directly to the site. To add a comment or ask a question please email the address in this image: and use Project 1 - Arduino NAMUR sensor control as a reference.