signalen doorgeven tussen 2 (meerdere) arduino's

Hey allemaal,

ik probeer tevergeefs om signalen door te geven tussen een UNO en een MEGA.
(zie schets)
aan de MEGA heb ik een neopixelstrip geplaatst aan P45 (~PWM)
alles zit samen aan één grote voeding (5V - 150watt)
de bedoeling is als ik via de button aan de UNO een signaal geef op P2 (al dan niet via een ISR), dat P8 dan hoog wordt en dat de P8 van de MEGA dit detecteert en dan de ledstrip laat oplichten…

ik dacht, dit wordt een eitje, maar niets is nog zeker in dit leven behalve de belastingsdruk :-X
ik had er aan gedacht om alle GND’s te verbinden via de arduino’s ook (alhoewel die volgens mij al op de voeding verbonden zijn)

momenteel lijkt het erop dat de MEGA-P8 continue een HIGH binnenkrijgt!?

ik wil doelbewust van de RX/TX wegblijven, omdat ik die later nog nodig heb voor andere communicatie…

helpt mij iemand terug op de goede baan?
Grtz,
Yves

test_uno_1.ino (423 Bytes)

test_mega_1.ino (2.01 KB)

Op de mega heb je verschillende rx/tx aansluitingen.
En op de uno kan je er een sofwarematige maken ook.
misschien dit toch overwegen ?

moet state^=state niet zijn state!=state ,?

vadeveni:
moet state^=state niet zijn state!=state ,?

Yup, die had ik intussen ook gevonden :slight_smile:
toch bedankt hiervoor...

volatile boolean state = LOW;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(2, INPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8,LOW);
  attachInterrupt(0, startLED, CHANGE);
}

void loop()
{
}

void startLED()
{
  state = !state;
  digitalWrite(8, state);
}

En, werkt het nu, of nog niet ?

Hoi.

Mogelijk heb je er een specifieke reden voor, maar die weerstand kun je weglaten.
En met 220 Ohm (volgens de schets) is ie wel een beetje laagohmig voor dat doel.
Ik zie dat je pin 8 met pin 8 hebt verbonden.
En in de code voor de MEGA zie ik eigenlijk alleen dit:

  pinMode(7, INPUT);

Was die pin 7 ergens anders voor bedoeld, of is dat degene waar je naar zit te kijken ?
Moet je 'm dan niet veranderen in:

  pinMode(8, INPUT_PULLUP);

Door de PULLUP (dus de interne pullup die wellicht juist weer een beetje hoog is), heb je de pull down in je schemaatje niet meer nodig.
Maar dan moet je 'm wel andersom aansturen.
Dus actief = laag.

Hey Mas3 & Vadeveni,

ik heb het idd werkend gekregen (die weerstand heb ik er uit gelaten)
mogelijks maak ik een nieuw schema, omdat ik nog wel even verder wil experimenteren met dit projectje

@MAS3 : dat is idd een typfout wat betreft die pinnen in de MEGA... ik lees wel degelijk de P8 uit

wat het experiment op zich betreft:
ik wil namelijk iets proberen met meerdere arduino's, om zo een soort PLC-achtige opbouw te kunnen maken (voor zover ik de werking van een PLC goed begrepen heb - ik ken daar echt géén jota van !!)

het idee is eigenlijk dat ik verschillende arduino's simultaan verschillende taken laat afhandelen en dan één arduino die iets doet met alle data en de verwerking ervan (wordt nog een hete aardappel, omdat ik nogal "ongeschoold" ben in dit soort materie).
Ik heb daartoe een aantal Pro micro's 5V/16Mhz besteld en heb hier thuis nog wat MEGA's en UNO's op overschot

maar anderzijds blijft het een kei-leuke bezigheid om zo'n dingen te proberen, en als er iets is wat ik WEL heb, dan is dat geduld en tijd.... :slight_smile:

alles wat ik probeer blijft uiteraard in het kader van m'n favoriete hondensport... zo heb ik een duidelijk afgelijnd doel voor ogen.

als er natuurlijk iemand mee wil brainstormen, altijd welkom natuurlijk :slight_smile:

deze avond ga ik eens aan de slag met het doelbewust 'delayen' binnen een ISR (delayMicroseconds(12000) ) om op die manier een soort debounce te maken (jammer dat je maar tot 16383 kan gaan ! - ik heb eigenlijk 120000 nodig :frowning: )

Grtz,
Yves

PS : weet er iemand waarom ik géén meldingen meer krijg van jullie reply's (ik heb toch alles ingesteld om ze net wel te ontvangen.... :frowning: )

Hoi,

Hierbij het nieuwe schema en de up-to-date code
eerst voor de UNO nr 1

/*
* Basic code for the first UNO(1)
* date : 15/08/2016
*/
void setup() {
  Serial.begin(115200);
  pinMode(2, INPUT);
  pinMode(8, OUTPUT);
  digitalWrite(8,LOW);
  attachInterrupt(0, startLEDs, RISING);
}

void loop()
{
}

void startLEDs() // ISR to send a signal to the MEGA 1 - this MEGA will start a light sequence
{
  digitalWrite(8,HIGH);
  delayMicroseconds(12000);
  digitalWrite(8,LOW);
}

en voor de MEGA2560

/*
 * Basic code for the first MEGA2560
 * date : 15/08/2016
*/
#include <Adafruit_NeoPixel.h>

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(6, 45, NEO_RGB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);
  strip1.begin(); //  initialiseer LEDstrip1
  strip1.show();
  strip1.setBrightness(255);
  pinMode(8, INPUT);
}

void loop() {
  if (digitalRead(8))
  {
    wit();
    delay(1000);
    clear_wit();
    rood();
    delay(1000);
    clear_rood();
    blauw();
    delay(1000);
    clear_blauw();
    geel1();
    delay(1000);
    clear_geel1();
    geel2();
    delay(1000);
    clear_geel2();
    groen();
    delay(1000);
    clearstrip1();
//    start = HIGH;
  }
}
// function zone
void clearstrip1()
{
  for (signed char i = 0; i < 7; i++)
  {
    strip1.setPixelColor(i, 0, 0, 0);
  }
  strip1.show();
}
// functies voor WITTE LAMP
void wit()
{
  strip1.setPixelColor(0, 255, 255, 255);
  strip1.show();
}
void clear_wit()
{
  strip1.setPixelColor(0, 0, 0, 0);
  strip1.show();
}
// functies voor RODE LAMP
void rood()
{
  strip1.setPixelColor(1, 255, 0, 0);
  strip1.show();
}
void clear_rood()
{
  strip1.setPixelColor(1, 0, 0, 0);
  strip1.show();
}
// functies voor BLAUWE LAMP
void blauw()
{
  strip1.setPixelColor(2, 0, 0, 255);
  strip1.show();
}
void clear_blauw()
{
  strip1.setPixelColor(2, 0, 0, 0);
  strip1.show();
}
// functies voor GELE LAMP 1
void geel1()
{
  strip1.setPixelColor(3, 255, 175, 0);
  strip1.show();
}
void clear_geel1()
{
  strip1.setPixelColor(3, 0, 0, 0);
  strip1.show();
}
// functies voor GELE LAMP 2
void geel2()
{
  strip1.setPixelColor(4, 255, 175, 0);
  strip1.show();
}
void clear_geel2()
{
  strip1.setPixelColor(4, 0, 0, 0);
  strip1.show();
}
// functies voor GROENE LAMP
void groen()
{
  strip1.setPixelColor(5, 0, 255, 0);
  strip1.show();
}
void clear_groen()
{
  strip1.setPixelColor(5, 0, 0, 0);
  strip1.show();
}

dit alles werkt lekker,
nu de uitbreidingen testen

Grtz,
Yves

Hoi Yves.

Als je nog meer Arduinos wil verbinden, dan zou je eens moeten overwegen een iets andere aanpak te gaan doen.
Want op deze manier ga je natuurlijk uiteindelijk veel pinnen gebruiken om alleen maar dat signaaltje te verzenden.
De andere aanpak zou een bus systeem zijn, zoals I2C of SPI.
Bij I2C ga je elke module een adres geven en ze dus allemaal tegelijk dezelfde data sturen, maar mag de data alleen verwerkt (en beantwoord) worden door die module die door de master aangesproken word middels diens adres.
Dan kun je de communicatie met 2 aders af.

Met RS485 kun je ook iets dergelijks opzetten, maar daarmee kun je een grote afstand overbruggen (tot 1200 meter bij 9600 baud).
I2C is daarvoor nooit bedoeld (I2C staat voor Inter - Integrated circuit -Communication, en is dus eigenlijk bedoeld voor communicatie tussen verschillende chips op een print of binnen een apparaat).
Daarvoor heb je wel de juiste kabeltypes en nog wat verdere voorwaarden nodig.
RS485 word dan ook bij veel van die "PLC's" c.q. tweedraads systemen toegepast, juist vanwege de relatief eenvoudige opzet en betrouwbaarheid.

Hey MAS3,

"tell me more, tell me more"..... :slight_smile:

vraagje, kun je dan nog evengoed met ISR's enzo blijven werken op de verschillende modules?

kun je dan ook data doorgeven in de zin van :
= 'Rode baan - Hond1 - StartTijd : 0,423sec - "geen fout" - ... '??
en kun je daaruit dan dingen filteren bvb welke hond er nu aan het lopen is, of als hij een fout had?

en dan de belangrijkste vraag nog : is dit iets dat ik als complete beginner "vlot" :slight_smile: voor elkaar kan krijgen
Grtz,
Yves

Yves ff googelen en je hebt het zo gevonden.
Overigens zou ik dus nooit eindeloze teksten over de lijn pompen maar gewoon een paar codes:

  • baan kleur (1 byte)
  • hond nummer (1 byte)
  • start tijd (6bytes)
  • fout code(1byte)

De ontvanger kan dan die codes decoderen. En dan houdt je nog maar 9 bytes voor een bericht.

Mee eens.

Het is een heel goed idee om de data die je genereert en die op de bus zoveel mogelijk te beperken.
Dus codes in plaats van complete resultaten.
Die resultaten hebben je Arduinos helemaal niet nodig, dat is alleen voor de user interface, de verbinding met die domme mens die de codes niet begrijpen zal.

Graag wijs ik je op Nick Gammon's tutorials, die zijn weliswaar in het Engels, maar zeer waardevol en een bookmark in je browser zeker waard.
Dat gaat over seriële communicatie, maar heeft raakvlakken met RS485, en je kunt compacte modules kopen die van Rx/Tx seriele verbindingen naar RS485 gaan.

Google biedt je ook veel informatie over I2C, maar ook daar kun je wat over vinden bij Nick Gammon.

Hey allemaal,

ik heb even wat zitten opzoeken, en ik ga momenteel eventjes het pad verlaten om via seriële communicatie te werken, ik denk dat ik daar momenteel nog iets te groen achter de oren voor ben...

anderzijds, ik heb nu eens zitten prielen met 2 arduino's

met de MEGA probeer ik een signaal uit de UNO te vangen (wat ook lukt)

maar met de UNO wil ik echt doelbewust de delayMicroseconds() gebruiken (met een waarde van 12000, binnen m'n ISR - maar kennelijk blijft de ISR wel degelijk werken (ik had er een groot aantal na elkaar gezet van 12000 om aan minimaal een drietal seconden te komen), mijn idee was namelijk dat hij ze één voor één ging uitvoeren, maar neen, hij vangt de signalen nog steeds op, als ik met een "propere" teller werk, dan kan ik de ISR voor een welbepaalde tijd inactief zetten, maar dan kan ik niet binnen diezelfde ISR het signaal naar de MEGA terug op LOW zetten :frowning:

mijn fotocellen geven een LOW signaal bij het onderbroken worden

mijn idee was eigenlijk om binnen de ISR op de UNO, via de instelling "FALLING", het signaal te capteren en een HIGH naar de MEGA te sturen, en dan na 0,12sec het signaal naar de MEGA toe terug op LOW te zetten, omdat ik bang ben dat ik anders het signaal op de MEGA zou mislopen... als hij bvb met iets anders binnen zijn -toch omvangrijke code - zou bezig zijn

Q: zie ik hier belangrijk over het hoofd ?

anderzijds is er ook nog de mogelijkheid om "CHANGE" te gebruiken, maar hoe pak ik dat dan best aan, want soms kruisen honden elkaar op de sensorslijn...
of werkt "CHANGE" met de status die er vooraf was

bvb : hond komt door sensor => CHANGE => signaal naar MEGA op HIGH => delayMicroseconds(12000) => hond verlaat sensor =>CHANGE => signaal naar MEGA op LOW

vorige week had ik geprobeerd met de variabele 'state' en dan bij CHANGE => "state = !state"
dus binnen de ISR

void ISR() 
{
digitalWrite(8,state);
state = !state;
delayMicroseconds(12000);
}

ik vrees dat ik een beetje het juiste pad kwijt ben momenteel (maar ik geef niet op natuurlijk :slight_smile: )

Grtz,
Yves

YvesD:
ik vrees dat ik een beetje het juiste pad kwijt ben momenteel (maar ik geef niet op natuurlijk :slight_smile: )

Grtz,
Yves

Anders ik wel...... :grin:

nicoverduin:
Anders ik wel...... :grin:

LOL Nico :slight_smile:

ik weet dat mijn uitleg nogal rommelig is.... maar ik weet niet goed hoe ik het anders moet verwoorden :frowning:

het is ook nogal complex met de bewegingen die de vier opeenvolgende honden doorlopen gedurende 1 enkele heat (= 1 raceonderdeel)
er moet op zoveel gelet worden, en zoveel foutafhandeling gebeuren, dat ik het soms niet uitgelegd krijg aan anderen
ik kan het visueel uitleggen, maar dan nog blijft het complexe materie om om te zetten in code...
daardoor kan ik best begrijpen dat mensen niet eeuwig kunnen blijven helpen of me op de goede richting zetten
al helemaal omdat ik sommige complexe dingen ook nog niet snap, en ik steeds moet terugvallen op experimenteren (wat uiteindelijk ook het basisidee van arduino is)

Grtz,
Yves

YvesD:
mijn idee was eigenlijk om binnen de ISR op de UNO, via de instelling "FALLING", het signaal te capteren en een HIGH naar de MEGA te sturen, en dan na 0,12sec het signaal naar de MEGA toe terug op LOW te zetten, omdat ik bang ben dat ik anders het signaal op de MEGA zou mislopen... als hij bvb met iets anders binnen zijn -toch omvangrijke code - zou bezig zijn

Met alle delays in de Mega code zul je die 'pulsen' vast wel eens missen :wink:

Misschien eens tijd om te kijken naar Demonstration code for several things at the same time en het 'blink without delay' voorbeeld dat bij de IDE zit.

Heb je echt die interrupt nodig in de Uno code? Geen idee wat die Uno allemaal voor werk moet (gaan) doen, maar gebaseerd op je eerste code heb je daar zeer vermoedelijk geen interrupt nodig. Hoe snel wil je dat sensor signaal doorgegeven hebben aan de Mega? Je kunt 1000 digitalReads doen in ongeveer 4 milliseconden. Wat extra code eromheen om het door te geven aan de Mega en je zit (met een beetje pech :wink: ) aan 10 milliseconden; dat is 10 microseconden per lezing.

Hey sterretje,

die delays in de mega-code, die gaan eruit hoor, dat was enkel om iets visueel weer te geven op een ledstrip :slight_smile:

wat betreft die interrupt in de UNO, had daar eigenlijk nog niet aan gedacht, maar die moet eigenlijk maar één iets doen, en dat is een pin op de mega hoog zetten, en direct erna (0,12s) terug laag zetten.... dus als ik het zo bekijk, dan heb ik die eigenlijk niet echt nodig denk ik... het risico dat ik een puls van de fotocel mis is eigenlijk zo goed als nihil nu je het zo omschrijft
vandaar dat ik voor de afzonderlijke rijen fotocellen (4 rijen van telkens 6 cellen) telkens 1 UNO wil gebruiken (heb die toch liggen, en heb ook een vijftal Pro Micro's onderweg)

ik heb deze avond wat tijd en kan dit wel eens proberen, er is ook een logic analyzer toegekomen om dingen zichtbaar te maken op een tijdlijn, eens ik die goed doorheb kan ik eigenlijk met honden gaan testen op het veld en dan de logic analyzer z'n gegevens rustig bekijken en eventueel opslaan

bedankt voor de insteek omtrent die ISR !!!

Grtz,
Yves