opugh
July 20, 2023, 4:18pm
1
I have 16 IR sensors (HW-201), and they are being used to detect slot cars as they pass. At slower speeds the cars are detected just fine, once the cars are going quickly they are detected 9/10 by my arduino mega. The LED to indicate object detection lights up every time the car passes, but the digitalread does not. I am assuming this is beacuse the sensor is high for such a short period of time.
I have had a few ideas to resolve this issue?
Tried using fast implementations of digitalRead - unfortunately not quick enough, and I don't think relying on reading in a loop will work
Setting them as interrupts, I have an arduino mega and that only supports 6 interrupts, and I have 16 inputs! I could maybe stretch to 2 megas and 8 on each, but three is out of budget and size budget for me.
Could I use some sort of flip flop system, or extend the signal in some way? Flip flops seem like they will take up even more pins and will need 32 pins just for the IR sensors! One for state and one for reset, which is possible but seems like I may be over complicating!
Could the cable length be affecting this at all? The cables from IR sensor to arduino is around 50cm.
Hello opugh
Post your current program to see how we can help.
J-M-L
July 20, 2023, 4:26pm
3
your code might not ping the sensor fast enough but we can't say how to fix this code without seeing it
(you could use pin change interrupt -PCINT0 and PCINT2 would give you 16 pins, enough for you 16 sensors)
opugh
July 20, 2023, 4:41pm
5
Sure! I didn't think the code would be of much use so I didn't include it!
Reading the sensor
#include <Arduino.h>
#include <digitalWriteFast.h>
#include "track_monitor.h"
Checkpoint::Checkpoint(int pin, int position)
: pin(pin), position(position)
{
pinMode(pin, INPUT);
}
int Checkpoint::getPosition()
{
return position;
}
int Checkpoint::getState()
{
return digitalReadFast(pin);
}
TrackMonitor::TrackMonitor(int *irPins, int numPins) : checkpointCount(numPins), checkpoints(new Checkpoint *[numPins]), lastCheckpoint(checkpoints[0])
{
// Iterate through the irPins array and create a Checkpoint object for each pin
for (int i = 0; i < numPins; i++)
{
checkpoints[i] = new Checkpoint(irPins[i], i);
}
}
int TrackMonitor::getPosition()
{
return lastCheckpoint->getPosition();
}
int TrackMonitor::getCheckpointCount()
{
return checkpointCount;
}
TrackMonitor::~TrackMonitor()
{
for (int i = 0; i < checkpointCount; i++)
{
delete checkpoints[i];
}
delete[] checkpoints;
}
void TrackMonitor::loop()
{
for (size_t i = 0; i < checkpointCount; i++)
{
if (checkpoints[i]->getState() == LOW) // means activated
{
Serial.print("detected open: ");
Serial.println(i + 1);
lastCheckpoint = checkpoints[i];
}
}
}
main
#include <Arduino.h>
#include "car.h"
#include "track_monitor.h"
#define NUM_LANES 2
struct Lane
{
Car car;
TrackMonitor trackMonitor;
};
int irPins1[] = {23, 25, 27, 29, 31, 33, 35, 37};
int irPins2[] = {};
float lane1Speeds[sizeof(irPins1) / sizeof(irPins1[0])] = {
0.1,
0.5,
0.1,
0.1,
0.1,
0.1,
0.1,
0.1};
Lane lanes[] = {{{M1_FORWARD, M1_BACK, M1_SPEED}, {irPins1, sizeof(irPins1) / sizeof(irPins1[0])}}, {{M2_FORWARD, M2_BACK, M2_SPEED}, {irPins2, sizeof(irPins2) / sizeof(irPins2[0])}}};
void setup()
{
}
void loop()
{
// run the loop for the sensors
lanes[0].trackMonitor.loop();
lanes[1].trackMonitor.loop();
int currPos = lanes[0].trackMonitor.getPosition();
lanes[0].car.setSpeed(lane1Speeds[currPos]);
}
J-M-L
July 20, 2023, 5:38pm
6
here is an example using PCINT where I only read the status of the port getting the action
the buttons in the simulation do not have bouncing to make it easy to see the result
see if that would react fast enough for you (of course printing is slow - you might want to increase baud rate)
Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!
source code for reference
// PCINT0 on pins 53 52 51 50 10 11 12 13 ( PORT B)
// PCINT2 A8 ... A15 (PORT K)
const uint8_t portBPins[] = {53, 52, 51, 50, 10, 11, 12, 13};
const uint8_t portKPins[] = {A15, A14, A13, A12, A11, A10, A9, A8};
enum ActionType : uint8_t {NONE, ACTION_PORTB, ACTION_PORTK};
volatile ActionType action = NONE;
volatile uint8_t portState;
ActionType actionCopy;
uint8_t portStateCopy;
void activatePCINT(uint8_t aPin)
{
*digitalPinToPCMSK(aPin) |= bit (digitalPinToPCMSKbit(aPin)); // enable it
PCIFR |= bit (digitalPinToPCICRbit(aPin)); // clear interrupt flag
PCICR |= bit (digitalPinToPCICRbit(aPin)); // enable interrupt
}
ISR (PCINT0_vect) {
action = ACTION_PORTB;
portState = PINB;
}
ISR (PCINT2_vect) {
action = ACTION_PORTK;
portState = PINK;
}
void printAction() {
for (int8_t i = 7; i >= 0; i--) Serial.write(bitRead(portStateCopy, i) == 0 ? '-' : '*');
Serial.println(actionCopy == ACTION_PORTB ? F("\tPB ") : F("\tPK "));
}
void setup() {
for (uint8_t aPin : portBPins) {
pinMode( aPin, INPUT_PULLUP);
activatePCINT(aPin);
}
for (uint8_t aPin : portKPins) {
pinMode( aPin, INPUT_PULLUP);
activatePCINT(aPin);
}
Serial.begin(115200);
Serial.println(F("Ready"));
}
void loop() {
switch (action) {
case NONE:
break;
case ACTION_PORTB:
case ACTION_PORTK:
// critical section
noInterrupts();
actionCopy = action;
portStateCopy = portState;
action = NONE;
interrupts();
printAction();
break;
}
}
opugh
July 20, 2023, 7:00pm
7
This is really interesting! And looks like it could well be the solution. I am looking at using 16 pins so will need to work out how to add a few more. I will give this a go and will report how I get on. Thank you!
b707
July 20, 2023, 7:11pm
8
Using Serial print of each active position make you code very slow.
BTW, it seems you use Serial without initialise it.
J-M-L
July 20, 2023, 7:21pm
9
I did not bother to add 16 buttons but you have 16 active pins
J-M-L:
// PCINT0 on pins 53 52 51 50 10 11 12 13 ( PORT B)
// PCINT2 A8 ... A15 (PORT K)
const uint8_t portBPins[] = {53, 52, 51, 50, 10, 11, 12, 13};
const uint8_t portKPins[] = {A15, A14, A13, A12, A11, A10, A9, A8};
That’s the ones to use
opugh
July 20, 2023, 7:28pm
10
You are dead right! I cleaned up the code to remove anything not useful for this post, I was just using serial to debug another issue and left them in! Good spot though!
opugh
July 20, 2023, 7:31pm
11
Ah I didn't spot that part! Thank you for your help!
opugh
July 20, 2023, 8:52pm
12
That worked perfectly! Thank you!
system
Closed
January 17, 2024, 6:40am
14
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.