Traplooplicht 2.0

Goedendag,

Ik heb vorig jaar een Arduino Uno gekocht tezamen met de PCA9685 16-kanaals PWM shield, 12 LED strips en 2 ultrasoon sensoren. Het idee was om een trapverlichting te maken die, afhankelijk van de richting, de traptreden 1-voor-1 zou laten oplichten en daarna weer langzaam zichzelf liet uitdoven. Samen met iemand anders waren we begonnen en was de code geschreven. Als triggers voor de looplichtcode (boven/onderaan de trap) gebruikten we ultrasoonsensoren, waarvoor ook een code geschreven was. Het signaal werd hoog indien de afstand, die door de sensor continu gemeten werd, kleiner werd (voet komt voorbij gelopen) dan een instelwaarde (overkant van de vrije traptrede).

Voor de test haalt de Arduino+shield zijn spanning uit de USB stekker. De shield heeft voor het schakelen van groot-vermogen trekkende LEDs-strips zijn eigen voeding bovenop de print (zie foto), maar voor deze test (en deze kleine ledjes) haal ik de spanning direct van de +5V en de GND pin bovenop de shield (2x gele draad bovenop). Ik heb de werking van de LEDs en PWM-shield eerst getest door een Knight-rider sketch te laden. Dat was gelukt dus alles was goed verbonden
Uiteindelijk bleek het schakelen met ultrasoonsensoren niet zo lekker te verlopen. We denken dat valse echo’s de sensoren op willekeurige moment leek te storen zodat het looplicht vervolgens soms ook in de war raakte. Daarom leek het mij een mogelijk alternatief als ik PIR-sensoren gebruik in plaats van de ultrasoon. Het leek mij goed mogelijk dat deze sensoren minder vals-positieven geven en de gevoeligheid is op het PIR-printje ook nog eens aan te passen. De PIR print geeft gedurende een paar seconden een HOOG +5V signaal indien er bewegende warmte gevoeld wordt. Dat signaal wil ik nu graag gebruiken als nieuwe trigger voor het aansturen van de looplichtcode

Er is dus een looplicht code, gemaakt voor het herkennen van een trigger uit ultrasoonsensoren en daar in wil ik nu graag de code voor het herkennen van een hoog PIR-signaal hiervoor verwisselen. Ik heb 2 PIR sensoren die dus fysiek en softwarematig moeten worden verwisseld met de “ongewenste ultrasoon” sensoren/code.
Ik heb als test even een PIR sensor aangesloten op Pin2 en getest of deze ook goed werkt. Met een code van deze site

(https://learn.adafruit.com/pir-passive- ... -w-arduino)

kon ik dat bevestigen. De testschakelaar in de ene foto en de PIR sensor op de andere foto zijn een testopstelling om een code te maken om Pin2 HOOG te krijgen.
Nu moet ik dus in de nieuwe looplichtcode beschrijven dat er bvb een inputPin 2 is en dat als deze HOOG is, dat dan de looplicht subroutine gaan draaien als vanouds. Hetzelfde geldt dan natuurlijk ook voor de 2e PIR sensor aan de andere kant van de trap. Op zich hoeft er aan de grootste gedeelte van de code niks te veranderen. Op dit moment loopt die led-routine pas als de echoUpPin of echoDownPin hoog zijn. Pin 2 en 4 kan men volgens mij blijven gebruiken voor het meten van de toekomsttige boven- en ondersensor. Ik zou dus het onnodige ultrasoon-proximity-triggergedeelte uit mijn huidige code willen slopen en deze vervangen door de PIR subroutine/code (echoUpPin 5 en echoDownPin 3 moet worden omgebouwd tot PIR HOOG signalen) zodat het triggeren correct beschreven wordt. Ik heb zelf echter nog niet genoeg verstand van het programmeren om deze verwisseling toe te passen. Hieronder staat de code die had gewerkt met de ultrasoonsensoren.

Ik zou graag van iemand willen horen hoe ik deze code moet aanpassen zodat ik uiteindelijk de 2 PIR sensoren aan de praat krijg. Mocht iemand anders een soortgelijke PCA9685 schakeling al op de plank hebben liggen, dan bied ik mijn excuses aan en heb ik niet goed genoeg gezocht.

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////// User settings, U may edit!! /////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////

de code komt in een 2e bericht (was te lang voor dit bericht)

De vraag staat overigens ook gesteld op

http://arduinoforum.nl/viewtopic.php?f=8&t=2876

om de kans op een bruikbaar antwoord te vergroten

20180213_092518.jpg

20180213_092552.jpg

20180213_092625.jpg

20180213_092721.jpg

20180213_092735.jpg

20180213_115627.jpg

PIR-sensor.jpg

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////// User settings, U may edit!! /////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////

#define SpeedOn 7 //Time speed leds turning on in mili seconds
#define SpeedOff 25 //Time speed leds turning off in mili seconds
#define AmoundLed 16 //Amound of leds you use, max 16
#define DetectdistanceUp 15 //Distance pingsensor upstairs can detect ( in CM! )
#define DetectdistanceDown 15 //Distance pingsensor downstairs can detect ( in CM! )
#define LedLevelSteps 10 //Number of steps to increase LED level.
#define LedLevelStepSize 20 //Step size to increase LED level.
#define MaxTimeLedsOn 1000 //Max number of runs the lights should stay on.
#define MinDelayBetweenTriggers 10 // Minimum number of runs between 2 triggers of the same sensor.

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////// Start program do not edit!! /////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////

#define trigUpPin 3 //Sensor upstairs
#define echoUpPin 2 //Sensor upstairs
#define trigDownPin 5 //Sensor downstairs
#define echoDownPin 4 //Sensor downstairs
#define ledDown 8 //Sensor downstairs indication ( not required )
#define ledUp 9 //Sensor upstairs indication ( not required )

#define UPPER_SENSOR true // Used to make the code better readable
#define LOWER_SENSOR false // Used to make the code better readable

#include <Wire.h>
#include <PCA9685.h>

PCA9685 ledDriver;

// Parameters to keep the state
long counter = 0;
boolean directionUp = false;
boolean ledswitchedOn = false;

// Check whether the LEDs must be on.
boolean ledOn() {
if (counter > 0) {
--counter;
}
return counter > 0;
}

// Check whether the LEDs must be on, given a sensor was triggered.
boolean ledOn(boolean upperSensor) {
if (counter == 0) {
// Start cycle.
counter = MaxTimeLedsOn;
directionUp = !upperSensor;
} else {
// cycle is already running
if (directionUp == upperSensor) {
// End has been reached.
counter = 0;
} else {
// Another trigger at start, thus reset counter.
counter = MaxTimeLedsOn;
}
}
return ledOn();
}

long get_distance(boolean upperSensor)
{
int triggerPin = upperSensor ? trigUpPin : trigDownPin;
int echoPin = upperSensor ? echoUpPin : echoDownPin;

// Send reset trigger to the triggerPin, with pulse of 10 msec high.
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
// Measure ping duration
long echoduration = pulseIn(echoPin, HIGH);
// Compute distance in cm. Devide by 2 because it is a 2-way travel.
// Devide by 29.1, which is number of microseconds per cm for the speed of sound. (sound-speed is 343 m/s)
return (echoduration / 2) / 29.1;
}

/// Get sensor status
boolean sensorIsTriggered(boolean upperSensor)
{
boolean detectDistance = upperSensor ? DetectdistanceUp : DetectdistanceDown;
boolean sensorActive = get_distance(upperSensor) < detectDistance;
return sensorActive;
}

void setup()
{
pinMode(trigUpPin, OUTPUT);
pinMode(echoUpPin, INPUT); //sonar upstairs
pinMode(trigDownPin, OUTPUT);
pinMode(echoDownPin, INPUT); //sonar downstairs
pinMode(ledDown, OUTPUT);
pinMode(ledUp, OUTPUT);

Wire.begin(); // Wire must be started!
ledDriver.begin(B101000); // Address pins A5-A0 set to B111000
ledDriver.init();
}

void loop()
{
// First check both sensors to make sure no event is missed.
boolean upperSensorTriggered = sensorIsTriggered(UPPER_SENSOR);
boolean lowerSensorTriggered = sensorIsTriggered(LOWER_SENSOR);
boolean ledNewState = ledswitchedOn;
if (upperSensorTriggered || lowerSensorTriggered) {
// At least one sensor is active, prefer upperSensor when both active
ledNewState = ledOn(upperSensorTriggered);
} else {
// No sensor triggered, just update the counters.
ledNewState = ledOn();
}
if (ledswitchedOn != ledNewState) {
// We must do something, since current state differs from new state

// Geen idee of de richting omhoog hetzelfde is als wat jullie "inverted" noemden.
// Desnoods veranderen in:
// boolean inverted = directionUp;
boolean inverted = !directionUp;
driveLeds(ledNewState, inverted);
}
}

// Test to show distance of the sensors on the LEDs
void showDistance()
{
long distUp = get_distance(true);
long distLow = get_distance(false);

if (distUp < distLow) {
// Show distance up
vuLeds(distUp, true);
}else {
vuLeds(distLow, false);
}
}

// On a scale from 0..100
void vuLeds(long value, boolean inverted)
{
int nrLedsOn = AmoundLed;
long maxDistance = 100;
if (value < maxDistance) {
nrLedsOn = static_cast((AmoundLed * value) / maxDistance);
}
for (int i = 0; i < AmoundLed; ++i) {
int lednr = inverted ? (AmoundLed - 1 - i) : i;
int ledLevel = i > nrLedsOn ? 0 : 255;
ledDriver.setLEDDimmed(lednr, ledLevel);
}
}

void driveLeds(boolean on, boolean inverted)
{
for (int i = 0; i < AmoundLed; ++i) {
int lednr = inverted ? (AmoundLed - 1 - i) : i;
for (int level = 0; level < LedLevelSteps; ++level) {
int ledLevel = on ? level : (LedLevelSteps - 1 - level);
ledLevel = LedLevelStepSize * ledLevel;
if (ledLevel > 255) {
ledLevel = 255;
}else if (ledLevel < 0) {
ledLevel = 0;
}
ledDriver.setLEDDimmed(lednr, ledLevel);
delay(on ? SpeedOn : SpeedOff);
}
}
}

use code tags please .....

ctrl-t in de ide doet wonderen met de leesbaarheid van je code

Beste Rob,

Bedankt voor je reactie. Ik ga eens uitzoeken wat dat betekent... Heb je verder misschien ook bruikbare tips over de vraag die ik had gesteld in dit topic?

Hoi vinnie78, welkom.

Om eerlijk te zijn lijkt dit een beetje op iemand die ergens binnen komt met een flinke doos in zijn handen, en die doos vervolgens aan een bureau leeg kiept, met de opmerking "zoek dit eens voor me uit".
Natuurlijk is dat nooit jouw bedoeling geweest, maar het geeft wel aan waarom iemand zijn vingers niet aan dit onderwerp wil branden.

Je hebt al een heel eind beschreven wat je wil en hoe je denkt dat te kunnen doen.
Maar nu ben je gestopt met dat uit te werken omdat je nog niet genoeg ervaring denkt te hebben.
Maar je hebt al wel verschillende tests uitgevoerd.
En daar kun je op voortborduren.

Mijn vingertoppen zijn een beetje schraal aan het worden omdat ik vaak dezelfde zaken blijf vertellen.
Maar ook hier is het advies dat je je niet uit het veld moet laten slaan door grote problemen die je ziet.
In plaats daarvan, moet je elk probleem dat je ziet, aanpassen en in kleinere problemen verdelen.
Dat doe je net zo vaak totdat die problemen helemaal geen problemen meer zijn en je zo al de oplossing ziet.
Doe dit met behulp van een stuk papier en een pen of potlood, want daarmee behoud je het overzicht gemakkelijk.

En als je dingen in je code verandert, zorg dan eerst dat je de oude werkende code opslaat, en de nieuwe code onder een iets andere naam (bijvoorbeeld door versienummer in de bestandsnaam op te nemen) opslaat.
Verder kun je beter geen regels verwijderen als je niet zeker weet dat je die niet meer nodig hebt.
Beter zou je die regels uitschakelen door er commentaar van te maken.
Dat doe je door die regels te laten beginnen met //

Je hebt wel hier vermeld dat je het op arduinoforum.nl ook hebt gevraagd (Het Nederlandstalig Arduino forum - Bekijk onderwerp - Traplooplicht 2.0), maar daar heb je het niet gemeld dat je de vraag dubbel stelt.
Nu weet ik niet waar ik zal antwoorden :confused:

Beste MAS3, eigenlijk had ik gehoopt en verwacht dat ik toch niet de eerste Nederlander zou zijn die deze schakeling/opstelling wilde bouwen en dat er vast en zeker toch wel ergens een complete sketch te vinden is die 2 sensoren gebruikt om een PCA9685 aan te sturen. In dat geval had iemand mij wellicht de link willen sturen waar ik die complete sketch op het internet kon vinden.

Ik ben geen hard-core programmeur en pretendeer dat eigenlijk ook niet te worden, ook al vind ik het allemaal reuze interessant. Verder dan gw-basic ben ik vroeger dan ook niet gekomen :slight_smile:

Het is zeker niet de bedoeling om mensen van dit forum aan het werk te zetten om "mijn probleem" op te lossen. Zoals ik het nu begrijp, is er dus niemand die een dergelijke kant-en-klare sketch kent. Dat maakt de oplossing voor mij wel wat langdradiger. Ik dacht dat met een beetje knip en plakwerk uit diverse sketches de oplossing snel geboden kon worden. Maar dat zie ik dus verkeerd. Ik zal er dus meer tijd in moeten steken.

Een beetje knip en plakwerk is meestal aanleiding voor een beetje ellende....