alexandros
Well-known member
I'm setting up an outdoor installation with lots of alarm lamps (the ones that spin around, like those on ambulances). and I'm running into all sorts of issues. I'm using PIR sensors which trigger a row of lamps (split in two parts, which fire together). The idea is that when someone walks by, the lamps start dimming in one after the other in two rows, simultaneously, and when all are light up, they dim out again one by one. My main issue is that lots of Teensies (they are 13 Teensy LC in total) just stop responding after some time. I know that the sensors do need some time without any movement when powered up in order to get a picture of the environment they need to track and that's not really the case as it is a public space and I can't know that no one will pass when the installation boots up.
Here's the code for one of the Teensies.
To dim the lamps I'm using this MOSFET module. The Teensy connects to the ground and PWM pins of the module, and the blue clamp of the module connects to the power supply. The lamps has its positive input connecting to the power supply positive, and its negative to the LOAD output of the MOSFET module. Things start OK, but after a while many Teensies seem to stop reacting.
My question is, does anyone think there is something wrong with the code or connections mentioned above?
I should mention that the environment is quite humid, and all the Teensies and MOSFET modules are enclosed in boxes like this (sorry, the page is in Greek). Whenever I reload the code the Teensies seem to work, but at some random point problems start to occur.
Here's the code for one of the Teensies.
Code:
#define RAMPTIME 1000
#define LAMPDEL 1000
#define RAMPHOLD 6000
#define TABSIZE 256
// maximum number of lamps in a row
#define NUMLAMPS 7
#define LOWVAL 50
#define HIGHVAL 255
/////////////////// PWM VARIABLES /////////////////
int pwmTab[TABSIZE];
unsigned long runDur = LAMPDEL * NUMLAMPS;
bool rampStarted = false;
int rampTarget = 0;
int lastTarget = LOWVAL;
int rampVals[2][NUMLAMPS];
int previousLamp[2] = {0, 0};
int numSteps = 0;
unsigned long stepDur = 0;
unsigned long curStepTimeStamps[2][NUMLAMPS] = { 0 };
unsigned long lampTimeStamps[2][NUMLAMPS] = { 0 };
unsigned long rampStartTimeStamp = 0;
unsigned long rampEndTimeStamp = 0;
bool lampsRunning[2][NUMLAMPS] = { false };
bool targetReached[2][NUMLAMPS] = { false };
int stepDir = 1;
bool waitingToEndRamp = false;
int pwmPins[2][NUMLAMPS] = {{3, 4, 6, 9}, {10, 16, 17, 20, 22, 23}};
int howManyLampsOnRow[2] = {4, NUMLAMPS};
//////////////// SENSOR VARIABLES /////////////////
int pirPin = 2;
int oldPirVal = 0;
void setup() {
for (int i = 0; i < TABSIZE; i++) {
pwmTab[i] = (float)pow(((float)i/(float)TABSIZE), 2) * TABSIZE;
}
for (int row = 0; row < 2; row++) {
for (int i = 0; i < NUMLAMPS; i++) {
pinMode(pwmPins[row][i], OUTPUT);
analogWrite(pwmPins[row][i], pwmTab[LOWVAL]);
rampVals[row][i] = LOWVAL;
}
}
pinMode(pirPin, INPUT);
delay(60000);
}
void loop() {
checkSensor();
if (rampStarted) runRamp();
else if (waitingToEndRamp) {
if ((millis() - rampEndTimeStamp) > RAMPHOLD) {
endRamp();
}
}
}
void checkSensor() {
int pirVal = digitalRead(pirPin);
if (pirVal != oldPirVal) {
if (pirVal) {
if (!rampStarted && !waitingToEndRamp) {
startRamp();
}
}
oldPirVal = pirVal;
}
}
void calcSteps() {
numSteps = abs(rampTarget - lastTarget);
if (rampTarget > lastTarget) stepDir = 1;
else stepDir = -1;
stepDur = RAMPTIME / numSteps;
}
void startRamp() {
rampStarted = true;
rampTarget = HIGHVAL;
calcSteps();
rampStartTimeStamp = millis();
}
void endRamp() {
if ((millis() - rampStartTimeStamp) > runDur) {
rampStarted = true;
rampTarget = LOWVAL;
calcSteps();
}
}
void runRamp() {
for (int row = 0; row < 2; row++) {
bool foundInactiveLamp = false;
for (int i = 0; i < howManyLampsOnRow[row]; i++) {
if (!lampsRunning[row][i]) {
if (!i) {
lampTimeStamps[row][i] = millis();
lampsRunning[row][i] = true;
previousLamp[row] = i;
}
else {
if ((millis() - lampTimeStamps[row][previousLamp[row]]) > LAMPDEL) {
lampTimeStamps[row][i] = millis();
lampsRunning[row][i] = true;
previousLamp[row] = i;
}
}
}
if (foundInactiveLamp) {
break;
}
}
}
for (int row = 0; row < 2; row++) {
for (int i = 0; i < howManyLampsOnRow[row]; i++) {
if (lampsRunning[row][i]) {
if ((millis() - curStepTimeStamps[row][i]) > stepDur) {
if (!targetReached[row][i]) {
rampVals[row][i] += stepDir;
for (int j = 0; j < howManyPinsToChangePWMFreq; j++) {
analogWrite(pwmPins[row][i], pwmTab[rampVals[row][i]]);
}
curStepTimeStamps[row][i] = millis();
}
}
if (rampVals[row][i] == rampTarget) {
targetReached[row][i] = true;
if ((i == (howManyLampsOnRow[row]-1)) && (row == 1)) {
rampStarted = false;
lastTarget = rampTarget;
for (int j = 0; j < 2; j++) {
for (int k = 0; k < howManyLampsOnRow[j]; k++) {
lampsRunning[j][k] = false;
targetReached[j][k] = false;
}
}
if (rampTarget == HIGHVAL) {
waitingToEndRamp = true;
rampEndTimeStamp = millis();
}
else waitingToEndRamp = false;
}
}
}
}
}
}
To dim the lamps I'm using this MOSFET module. The Teensy connects to the ground and PWM pins of the module, and the blue clamp of the module connects to the power supply. The lamps has its positive input connecting to the power supply positive, and its negative to the LOAD output of the MOSFET module. Things start OK, but after a while many Teensies seem to stop reacting.
My question is, does anyone think there is something wrong with the code or connections mentioned above?
I should mention that the environment is quite humid, and all the Teensies and MOSFET modules are enclosed in boxes like this (sorry, the page is in Greek). Whenever I reload the code the Teensies seem to work, but at some random point problems start to occur.