Go Down

Topic: RX/TX of Software Serial gebruiken om commando's te versturen ipv pinnen hoog te (Read 620 times) previous topic - next topic

YvesD

Hey allen,

ik heb een tweeledige vraag (beide over dingen waar ik totaal geen ervaring mee heb)

1) Kun je een RX/TX signaal parallel doorlussen naar meerdere arduino's of toebehoren (zoals bvb HC-05)
2) Kun je via Software serial (of toch via RX/TX) een soort string doorsturen naar een arduino, waarna je naargelang de waarde die je toestuurde een bepaalde actie kan ondernemen (bvb een LED doen oplichten), en via de HC-05 dan deze string zichtbaar maken via bvb de BlueTerm app op Android.

bedenkingen bij 1)
eigenlijk heb ik enkel nood aan het verzenden van data naar een tweede unit (arduino of HC-05) maar ik weet niet of er na de ontvangst een soort "goed ontvangen" signaal teruggestuurd wordt naar de verzender...
bedenkingen bij 2)
als ik effectief zou kunnen dezelfde data naar een arduino EN een HC-05 zenden, dan kan ik mogelijks aan de hand van de ontvangen string een actie ondernemen:
als de string "ROOD" is bvb een rode led aansturen die op een pin zit, als de string daarentegen "GROEN" is een groene led aansturen die op een andere pin zit... lijkt eenvoudig maar voor mij is dit toch een redelijk vraagstuk.
mij lijkt dit op te vangen met "switch...case...", maar mogelijks is dit enkel een droombeeld van mij, toch?

bedenking in het algemeen, is het op zo'n moment mogelijks verstandiger om bvb software serial te leren gebruiken omdat ik dan een UART vrij houd voor andere dingen.

hardware : 2x Pro Micro 5V/16Mhz, 1x HC-05

Grtz,
Yves

nicoverduin

Technisch kan het. De halve wereld werkte vroeger al zo over modems
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

MAS3

Hoi Yves.

Je hebt 2 stuks Pro Micro vertel je.
Dat is mooi, want die heeft zowel een interne USB verbinding, als een seriële verbinding.
Hoewel ik ook zo'n boardje heb, weet ik nog niet of die twee met elkaar verbonden zijn want ik heb er nog niet voldoende mee gespeeld.
Maar natuurlijk kun je de RX van het 2e boardje met de TX van het 1e boardje met elkaar verbinden (en vice versa), en het 1e boardje laten herhalen wat ie ontvangt.

Ik zou niet zoeken naar de tekst rood (of ROOD), maar als de r binnenkomt zou ik al voldoende weten.
Tenzij je veel meer wil versturen over die seriële verbinding.

Het seriële protocol (voor zover je daarover kunt spreken), is heel simpel.
Er gaat gewoon data heen en weer.
En als je daar een of andere controle op wil doen, dan moet je gewoon meer data versturen.
Zoals een checksum, plus een antwoord dat vertelt of de checksum klopte of niet.
Maar dan ben je alweer een eigen protocol aan het maken.
Dus dat zit er bij deze wijze van communiceren niet standaard ingebakken.
Overigens biedt een checksum een grote verbetering, maar echt 100 % zeker van een goede overdracht ben je dan nog steeds niet hoor.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

YvesD


Hey,

ben nu even aan het experimenteren en heb het volgende geschreven:
op ProMicro1 (verzender) :
Code: [Select]


boolean FaultStartState = LOW;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(115200);
}

void loop()
{
    if (digitalRead(Button1) && !FaultStartState)
    {
      Serial.println("FOUT START !");
      Serial1.write('R');
      FaultStartState = HIGH;
    }
}



op ProMicor2 (ontvanger) :

Code: [Select]


char      CharLights;
boolean NewLightCommand = LOW;


void setup()
{
  Serial.begin(9600);
  Serial1.begin(115200);
}

void loop()
{
 readSerial();
}




void readSerial()
{
  if (Serial1.available() > 0)
  {
    CharLights = Serial1.read();
    NewLightCommand = true;
    Serial.println("received");
  }
}

void SetFaultLamp()
{
  if (NewLightCommand)
  {
    switch (CharLights)
    {
      case 'R':
        Red(); // is gewoon een functie om een RGB ledstrip aan te sturen
        NewLightCommand = false;
        break;
      case 'G':
        Green(); // is gewoon een functie om een RGB ledstrip aan te sturen
        NewLightCommand = false;
        break;
      case 'r':
        ClearRed(); // is gewoon een functie om een RGB ledstrip aan te sturen
        NewLightCommand = false;
        break;
      case 'g':
        ClearGreen(); // is gewoon een functie om een RGB ledstrip aan te sturen
        NewLightCommand = false;
        break;
    }
  }
}


nu krijg ik wel de boodschap "received" op de ProMicro2 maar geen effect van de switch..case

ik weet wel heel zeker dat ik iets niet juist doe, maar weet niet aan wat het ligt, want als ik ipv 
Code: [Select]

...
Serial.println("received");
...

Serial.println(CharLights);



schrijf, dan krijg ik niets op de monitor


Grtz,
yves

MAS3

Hoi.

Je krijgt nu te zien dat je iets ontvangt, maar ik zou er bij zetten wat je dan ontvangen hebt.
Dat doe je via de seriële verbinding via de USB port, en dat is een krachtig debug hulpmiddel.
Wees niet bang dat meer te gebruiken.

Dus:

Code: [Select]
    Serial.print("received: ");
    Serial.println(CharLights);


Dan zie je dus niet alleen dat er iets ontvangen is, maar ook wat er ontvangen werd.
Aan je laatste stukje code te zien heb je zoiets al eens geprobeerd.

Wellicht krijg je iets anders binnen als je denkt.
Aangezien je maar 1 karakter verwacht (is dat werkelijk wat je krijgt ?*), zou je eens kunnen proberen wat er gebeurt als je een Serial.write doet.
Net zoals je in de zender doet trouwens.

Verder zie je niets gebeuren zeg je.
Maar ik zie ook niet wat er dan gebeuren zou, want de betreffende functie(s) heb je niet bijgevoegd.
Ik zou ook eens wat meer verzenden naar Serial tijdens je switch...case.
Je kunt precies laten zien wat er allemaal gebeurt terwijl de binnengekomen waarde door de switch.., case valt (zo zie ik dat).
Als ie ergens in een passend gat valt (omdat ie een R is bijvoorbeeld), zend dan via Serial dat je m gezien hebt.
En als ie nergens in een passend gat gevallen is, dan voorziet switch...case daar ook in, door de default case.
Dat is altijd de laatste case in de lijst, en daar kun je mooi via Serial laten weten dat de betreffende waarde nergens paste, maar dan weet je dus wel dat ie verwerkt werd.

Zoals je ziet, ik ben een fan van switch...case.
Ik heb ook al eens een leuke code gemaakt die data via een seriële verbinding volgt, en de voor mij van belang zijnde waardes decodeert en toont op een LCD.
Daarbij gebruik ik ook switch...case mechanismen, ook al heb ik inmiddels een iets efficiëntere wijze gevonden om hetzelfde te doen voor 1 daarvan.



*)
Een char is wellicht te enthousiast zolang het om een enkel karakter gaat.
Want ook al verzend je een karakter, er wordt in werkelijkheid een numerieke waarde verzonden (een getal dus).
Char heeft volgens mij niet veel zin in dat geval, en als het een char array word, dan mis je nog iets.
Want die array van 1 te verwachten karakter, is 2 karakters lang omdat ie moet worden afgesloten met een nul karakter.
Das mooi en "heel interessant om te weten", maar in het geval van een enkel karakter is het nogal zinloos naar mijn idee.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

YvesD

Je krijgt nu te zien dat je iets ontvangt, maar ik zou er bij zetten wat je dan ontvangen hebt.
Code: [Select]
   Serial.print("received: ");
    Serial.println(CharLights);

ik heb dit nu eens gedaan en krijg netjes :
'received: R' op de monitor, maar mijn switch..case valt niet door, zelfs de default niet
heb nu dit staan :
Code: [Select]
void readSerial()
{
  if (Serial1.available() > 0)
  {
    CharLights = Serial1.read();
    NewLightCommand = HIGH;
    Serial.print("received :");
    Serial.write(CharLights);
  }
}

void SetFaultLamp()
{
  if (NewLightCommand)
  {
    switch (CharLights)
    {
      case 'R':
        Red();
        NewLightCommand = LOW;
        Serial.println("Received Red");
        CharLights = "";
        break;
      case 'G':
        Green();
        NewLightCommand = LOW;
        Serial.println("Received Green");
        CharLights = "";
        break;
      case 'r':
        ClearRed();
        NewLightCommand = LOW;
        Serial.println("Received clear Red");
        CharLights = "";
        break;
      case 'g':
        ClearGreen();
        NewLightCommand = LOW;
        Serial.println("Received clear Green");
        CharLights = "";
        break;
      default:
        Serial.println("Nothing received !");
        break;
    }
  }
}

ahja, de LED functies zijn gewoon NeoPixel functies die aangepast zijn (en werken :) )
Code: [Select]
void Red()
{
  Lights.setPixelColor(3, 255, 0, 0);
  Lights.show();
}
void ClearRed()
{
  Lights.setPixelColor(3, 0, 0, 0);
  Lights.show();
}


enzovoort voor groen


ik vrees eigenlijk dat ik het verkeerde uitlees binnen "CharLights", ik probeerde met enkele aanhalingstekens, dubbele, en enkel de enkele werken, volgens mij omdat het slechts om één karakter gaat, en als je meer nodig hebt dat je dan dubbele moet gebruiken, toch
ik had ook al zitten denken aan een string variabele, maar weet niet of dat zo'n goed idee is

Grtz,
yves

nicoverduin

En waar roep je deze aan : SetFaultLamp() ? Anders gebeurt er gewoon niets
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

MAS3

Dat had ik dus gemist.
Krijg je ervan als je midden in de nacht gaat antwoorden.

Maar ook omdat we slechts delen, en niet de gehele code te zien krijgen.

Overigens is "Nothing received !" met zekerheid niet waar.
Het kan wel zijn dat er een foute of niet herkende waarde werd ontvangen.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

YvesD

En waar roep je deze aan : SetFaultLamp() ? Anders gebeurt er gewoon niets
O E P S S S !!!

Best dat er geen webcam op m'n gezicht staat  :-[ ik had net na m'n laatste reply in de gaten gekregen dat ik die functie inderdaad niet aanroep in de loop() ... op die manier gebeurd er echt niet veel natuurlijk
Dus die aanroep er wel ingezet, en dan werkt het (uiteraard  ;)  wel natuurlijk)
Nu wil ik proberen om meerdere dingen in één string te vervatten en die dan in stukjes op te delen en te "parsen", zodat ik met alle stukjes informatie aan de slag kan (bvb naar een LCD'tje, en wat LED's aansturen)
Ik had dan wel al begrepen dat ik met een char array zal moeten werken en mijn code als dusdanig aanpassen bij het inlezen van de Serial1 in dit geval...

Word vervolgt...

PS1 : Nico, hoe ver ben jij eigenlijk opgeschoten met je HMI scherm van Nextion? Heb dat een tijdje gevolgd, maar wegens tijdsgebrek al zeer lang niet meer nagekeken
PS2 : ik post hier straks m'n beide ino's, zo heeft iemand er mogelijks ooit nog iets aan

Grtz,
Yves

nicoverduin

Die draait als een tierelier. Wel moet begrijpen hoe event driven ontwikkelen werkt( dus gewoon de voorbeelden) die komen uit de nextion-arduino library van itead. Anders is het dweilen met de kraan open....
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

YvesD

Hey zoals beloofd mijn code voor de 2 Pro Micro's

in de code zie je dat ik nog diverse pinnen heb gereserveerd om acties door te sturen naar de ProMicro2
die komen nu wellicht te vervallen doordat ik met de RX/TX aan de slag kan gaan en aldus extra data wil proberen te versturen.

iets in de vorm van : "<R,2351402,SF>"
waar R dan staat voor een Rode led oplichten, 2351402 voor een tijdsopname, en SF voor het type fout (bv StartFout)

dan zou ik daaruit het volgende willen halen :

Code: [Select]
char ColorCodeDog[1]; // R is eerste hond (B=2, Y=3, G=4)
long TimeTrapDog1[10]; // 2351402 is microseconden waarop de fout gebeurde
char FaultCode[2]; // type fout - SF is een StartFault


wordt vervolgd :) 

Grtz,
Yves

MAS3

Ik ben benieuwd.

Zoals eerder aangegeven moet je niet per se veel data versturen, zolang je maar precies weet waar je bent.
Dus is "SF" echt nodig, of kun je volstaan met een enkel karakter dat het type fout aangeeft ?
Als je alle tekens in het alfabet plus getallen telt (maar waarom zou je je daartoe beperken), dan kun je al 62 foutcodes genereren (inclusief de foutcode die geen fout betekent).
Scheiden met een komma is een heel goed idee.
In mijn eerder beschreven code heb ik een "comma counter" ingebouwd, en die is heel handig.
Hetzelfde geldt voor beginnen met een bepaald teken (<), en eventueel eindigen met een ander bepaald teken (>).
Welk teken je daarvoor kiest maakt niet zoveel uit, zolang dat teken niet conflicteert met de content die je wil verzenden.
Op die wijze creëer je je eigen 'protocol'.
Probeer daarbij wel vooruit te denken en te voorzien in eventuele uitbreidingen in de toekomst.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

sterretje

iets in de vorm van : "<R,2351402,SF>"
waar R dan staat voor een Rode led oplichten, 2351402 voor een tijdsopname, en SF voor het type fout (bv StartFout)

dan zou ik daaruit het volgende willen halen :

Code: [Select]
char ColorCodeDog[1]; // R is eerste hond (B=2, Y=3, G=4)
long TimeTrapDog1[10]; // 2351402 is microseconden waarop de fout gebeurde
char FaultCode[2]; // type fout - SF is een StartFault

Ik vermoed dat je het 'protocol' hebt afgekeken van Serial input basics - updated. Dat draadje heeft ook een voorbeeld om de ontvangen informatie te splitsen.

Voor het omzetten van een tekst naar long kun je atol() gebruiken, voor het omzetten van tekst naar unsigned long kun je kijken naar strtoul().

Aangezien je gestructureerde informatie ontvangt, kun je overwegen om het op te slaan in een struct. Ik heb geen duidelijk idee wat de informatie precies is dus heb ik de struct maar even WHATEVER genoemd.

Code: [Select]
struct WHATEVER
{
  char ColorCode;
  unsigned long TimeTrap;
  char FaultCode[3];
};

Ik heb de foutcode 3 characters gemaakt zodat je nul-terminated karakter arrays kunt gebruiken en simple functies zoals bv. strcmp() om te vergelijken. Als je, zoals MAS3 voorstelt, een enkel karakter gebruikt, hoeft het geen array to zijn.

Ik heb ook de TimeTrap veranderd naar unsigned long; je kunt het aanpassen indien je dat niet nodig vindt.

Je kunt de velden in de struct op de volgende manier gebruiken
Code: [Select]

WHATEVER whatever;
 
whatever.ColorCode = 'R';
whatever.TimeTrap = 33;
strcpy(whatever.FaultCode, "SF");

Uiteraard zul je de velden de waardes moeten geven die je uit de ontvangen informatie hebt getrokken ;)

Verder een kleine opmerking over je ProMicro_1_lights_testing_module_lichten.ino in antwoord #10.

In SetFaultLamp() heb je een default case; de tekst is (naar mijn mening) incorrect omdat je daar nooit zou komen als er niks ontvangen was. Het is waarschijnlijk beter om daar iets te printen van "Incorrect value" gevolgd door de waarde.
Ook wordt in de default case de NewLightCommand variabele niet gewist en dus zal iedere keer dat je SetFaultLamp aanroept nadat je eenmalig een ongeldig karakter hebt ontvangen die melding naar de seriele poort worden gezonden totdat je weer een geldig karakter ontvangt.

Hetgeen me bij het volgende punt brengt; in alle cases wordt de NewLightCommand variabele gewist. Als je dat ook gaat doen in de default case, kun je het wissen net zo goed doen buiten de switch.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

YvesD

Ik vermoed dat je het 'protocol' hebt afgekeken van Serial input basics - updated.
Hey sterretje!,
inderdaad, daar ben ik de mosterd gaan halen  :)


nu, ik ben nog maar pas aan het eerste voorbeeld bezig hoor, als ik zie wat een mogelijkheden dit te bieden heeft, dan ben ik nog effe bezig me dunkt  :o


trouwens ook nog bedankt voor de tips i.v.m. de conversie functies van de ontvangen data


@iedereen : is het eigenlijk aangewezen om een nieuw "draadje" (zoals sterretje dat zo mooi noemt  :)) te starten, om op die manier alles wat samen te houden, of is dat eerder not-done op dit forum, en moet je voortbouwen op deze thread? Of is het niet gewenst om je experimenten aan de gemeenschap kenbaar te maken tot je een probleem hebt of net een oplossing hebt voor of met iets?

Grtz,
Yves

MAS3

Ik weet niet precies wat je bedoelt met die laatste vraag.
Ik zag weer wat over honden voorbij komen, en dus vermoed ik dat dit een deel is van waar je eerder al mee bezig was, of een toevoeging daaraan.

In dat geval zou je kunnen concluderen dat deze thread (i.e. draadje) bij de andere thread gevoegd zou moeten worden.
Maar het betreft wel een ander probleem met andere vragen.
Wanneer je het helemaal perfect zou willen doen en je een volgende andere vraag hebt, zou je kunnen verwijzen naar deze en je andere thread(s).
Zo kan iemand die je wil helpen herinnerd worden aan het verleden voor jou, en zien wat je allemaal al kent en gezien hebt.
Daardoor kan er mogelijk een passender antwoord gegeven worden, ook door iemand die jouw historie niet kent.
Maar heel erg nodig is dat nou ook weer niet wat mij betreft.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Go Up