Pages: 1 ... 3 4 [5] 6 7   Go Down
Author Topic: Arduino und der Sparkfun Transceiver nRF2401A ???  (Read 6001 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 2
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo kimmi

Quote
Bleibt das Programm dann am "while" einfach stehen oder durchläuft es weiterhin "void loop"?

Es "bleibt stehen" bzw. die loop-Funktion wird nicht verlassen bevor die while-Schleife beendet ist.

Du kannst während der While Durchläufe im Rumpf der while Schleife etwas ausführen lassen (so wie in meinem Beispiel mit der Ausgabe auf der seriellen Schnittstelle) oder Dich mit Timer-Interrupts anfreunden. Für den Anfang sehr geeignet ist diese Bibliothek hier
http://www.arduino.cc/playground/Main/MsTimer2

Schönes WE
Peter
« Last Edit: May 09, 2009, 09:09:23 am by dh1ao » Logged

Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bedeutet das, dass ich den gesamten Rest, den ich tun möchte innerhalb der "while" Schleife unterbringen kann?


Als Fernziel habe ich folgendes vor:

Ich möchte ein dezentrales selbstorganisiertes Netzwerk bauen, bei dem die gesamte Intelligenz auf den Kontotenpunkten liegt, es wird keine zentrale Steuerung geben.

Die Einheiten müssen aber neben ihren Steuerungs- und Handlungsaufgaben permanent auf Empfang sein.

Das Netzwerk soll ohne Synchronisation auskommen, daher ist eine getaktete Kommunikation - nach dem Motto: alle arbeiten vor sich hin und kommunizieren dann alles 1 Sekunde miteinander - nicht möglich.

Ich müsste, wenn ich das mit der "while" Schleife richtig verstehe, den gesamten Rest des Programmes innerhalb der "while" Schleife unterbringen. Ist das nicht zuviel, läuft dann die "while" Abfrage nicht zu langsam?

Oder ist es vielleicht möglich, dass der Transceiver ohne zutun den Arduino/Mikrokontroller detektiert ob ein Signal kommt und dann den Arduini über einen Interrupt - muss dann wohl ein Hardware Interrupt sein - aus seiner Momentanen Tätigkeit reißt und ihm den Datenempfang ermöglicht?

Ich muss da sozusagen jetzt die richtigen Weichen stellen, sonst entwickele ich in die falsche Richtung.

Da wäre nun wahrscheinlich das "Don´t start building a cathedral" angebracht was ?!  :smiley
« Last Edit: May 09, 2009, 02:47:46 pm by oren » Logged

0
Offline Offline
Jr. Member
**
Karma: 2
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo kimmi

Quote
Bedeutet das, dass ich den gesamten Rest, den ich tun möchte innerhalb der "while" Schleife unterbringen kann?

Prinzipiell schon, aber geschickt ist es IMHO nicht.

Langsamer wird's nicht wirklich (die loop() Funktion wird ja auch in einer while-Schleife im Bootloader aufgerufen) , allerdings hängt viel davon ab, wie lange Deine Aufgaben in der While-Schleife laufen.


Quote
Die Einheiten müssen aber neben ihren Steuerungs- und Handlungsaufgaben permanent auf Empfang sein.
Wenn die Befehle in einem Schleifendurchlauf  zu lange dauern, könnte es passieren, dass einkommende Zeichen verloren gehen.

Normalerweise empfängt man Daten über Schnittstellen Interrupt gesteuert. Wenn die noch zu findende RF Hardware bei Empfang ein digitales Signal abgibt, könnte das hier helfen

http://www.arduino.cc/playground/Main/PcInt

Ansonsten mit einem Timer alle xyz ms mal nachschauen.

Wenn ich Dich richtig verstanden habe willst Du mehrere Systeme autonom laufen lassen, die sich gegenseitig a'la Broadcast Informationen zukommen lassen; das ganze komplett ohne Syncronisation?
Nicht das da auf einmal alle losquatschen und sich gegenseitig in's Wort fallen (denk da so an CDMA Verfahren) oder riesen "Traffic" veranstalten...

Kurz und gut
in der While Schleife möglich, wenn while Schleife zeitlich kurz
Hardware Int der RF Hardware optimal
Timer basiertes Pollen mittelgut bei hoher Nachrichten Last

Viele Grüße
Peter
Logged

Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Also wenn ich das richtig verstehe, bildet die While-Schleife des Empfangs den Rahmen um das restliche Programm, da ich keine parallele Empfangsschleife im Hintergrund laufen lassen kann - das gibt es bei Arduinos wohl nicht.

Als Hardware bleibe ich erstmal bei dem Sparkfun Transceiver nRF2401A , ob der sowas wie ein wake-on-signal hat muss ich noch in den Specs nachsehen.


Was das eher nicht vorhandene Funkprotokoll angeht, es wird nur sehr wenig und selten Funkverkehr geben, da die Funkknoten sich nur koordinieren und keine konkreten Werte austauschen. Das Netzwerk wird nicht dem Datentransport dienen sonder ausschließlich der Netzkoordination.
Überschneidungen und Kollisionen der Signale sind daher unwahrscheinlich.

Das ganze wird ein etwas spezielles udn eigenartiges Gebäudeautomationssystem.
Logged

0
Offline Offline
Jr. Member
**
Karma: 2
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

im Datenblatt steht

Quote
nRF2401A then notifies (interrupts) the MCU by setting the DR1 pin high
und sobald man das Empfangsregister ausgelesen hat
Quote
When all payload data is retrieved nRF2401A sets DR1 low again,

Schon mal sehr gut dem Dinge. Ich lese im Datenblatt allerdings auch was über Adressen?

Quote
Address automatically removed from received packet in ShockBurst™
mode. In Direct mode MCU must handle address.

Kann sein, dass man keine braucht, seh ich aber grad nicht...

Quote
da ich keine parallele Empfangsschleife im Hintergrund laufen lassen kann - das gibt es bei Arduinos wohl nicht.
Kenne ehrlich gesagt keinen single-core Prozessor der das kann. Üblicherweise bastelt man sich mit einem Timer einen mehr oder weniger schlauen Scheduler. Im Arduinochen gehts etwas eng zu, daher kann man nicht so asen. Ich lass mir mal ein Beispiel einfallen.

Gruß
Peter
Logged

Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich glaube der Interrupt funktioniert nur mit dem Shockburst Mode, den für den Direct Mode geben sie folgendes an:

Code:
Direct Mode Receive:
MCU interface pins: CE, CLK1, and DATA
1. Once the nRF2401A is configured and powered up (CE high) in direct RX
mode, DATA will start to toggle due to noise present on the air.
2. CLK1 will also start to toggle as nRF2401A is trying to lock on to the
incoming data stream.
3. Once a valid preamble arrives, CLK1 and DATA will lock on to the
incoming signal and the RF package will appear at the DATA pin with the
same speed as it is transmitted.
4. To enable the demodulator to re-generate the clock, the preamble must be
8 bits toggling hi-low, starting with low if the first data bit is low.
[glow]5. In this mode no data ready (DR) signals is available. Address and
checksum verification must also be done in the receiving MCU. [/glow]

Die Arduino Library unterstützt aber so wie die Programme aufgebaut sind, nur den Direct Mode un damit keinen Interupt.

Was die Adressierung in der Nrf240 Library angeht, muss ich mla testen ob die auch ohe Adressierung funktioniert. Ansonsten setze ich erstmal alle Adressen auf die gleiche Nummer, dann sind sie eigentlich auch ohne Adresse.

Ob schon mal jemand versucht hat zwei Prozessoren auf ein Arduino-Mini-Pro Board zu bauen um zwei Prozesse parallel alufen zu lassen? Und die dann über eine Schnittstelle (SPI?) zu verbinden? So als kleinen Bruder des Quadcore Arduino?
Falls ja..her damit.
Logged

0
Offline Offline
Jr. Member
**
Karma: 2
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so, erstmal ein Beispiel für Nebenläufigkeit per Timer
Code:
#include <MsTimer2.h> // aus dem Playground

/* LED blinkt, ohne das in loop() was gemacht wird. In loop() wird nur gedimmt... */


/*
 *   Ein/Ausgabe Pins festlegen
 *  
 *   ledBlinkPin ist der digitale Pin für die LED, die blinken soll
 *   ledDimmPin  ist der digitale Pin für die LED, die per Taster gedimmt werden soll
 *   tastenPin   ist der digitale Eingangspin, an der der Dimmertaster angeschlossen ist (Eingang durch Taster gegen GND)
 */

int ledBlinkPin = 13; // weil der schon einen Vorwiderstand hat
int ledDimmPin  = 9;  // PWM fähiger Pin (Vorwiderstand nicht vergessen
int tastenPin   = 12; // irgendein freier digitaler Pin


/*
 * Funktion, die vom Timerinterrupt aufgerufen werden soll
 * Muss void blubblah(void) Signatur haben (also keine Parameter erwarten und auch nix zurückgeben)
 */
void timerCallback( void )
{
  blink( ledBlinkPin ); // hier wird die LED An/Aus Funktion zyklisch durch Timers aufgerufen
  /* hier könnten natürlich auch noch weitere Funktionen "im Hintergrund" ablaufen */
}

/*
 * Funktion, die eine LED ein/ausschaltet und aus der Timercallback aufgerufen wird
 */
void blink( int ledpin )
{
  static boolean ledAnAus = LOW; // static, damit der aktuelle Wert nicht zwischen zwei Aufrufen verloren geht
  
  ledAnAus = !ledAnAus;          // neuer Wert = invertierter alter Wert
  digitalWrite( ledpin, ledAnAus ); // und raus damit
}

/*
 * Funktion, die eine LED per PWM dimmt
 */
void dimm( int ledpin )
{
  static byte dimmval = 0;  // static ist klar...

  // bei jedem Aufruf ein Tick heller werden (dimmval++)
  // bei dimmval=255 wird's wieder 0, weil Byte nur 0...255 hat. 255+1 = 0 (Überlauf)
  analogWrite( ledpin, dimmval++ );

  delay(10); // sonst sieht man nur ein Glimmen
}

/*
 * Initialisieren
 */
void setup( void )
{
  // Das übliche Einstellen (OUTPUT muss eig. nicht da default)
  pinMode( ledBlinkPin, OUTPUT );
  pinMode( ledDimmPin,  OUTPUT );
  pinMode( tastenPin,   INPUT );

  digitalWrite( tastenPin, HIGH );   // PullUp benutzen
  
  // Dieses Konstrukt (Klassenmethode) stellt ein,
  // dass alle 500 ms (1.Parameter) die Funktion timerCallback (2. Parameter)
  // aufgerufen wird
  MsTimer2::set( 500, timerCallback );
  
  MsTimer2::start( ); // ab jetzt wird zyklisch die timerCallback aufgerufen (sozusagen ein nebenläufiger Prozess)
}

/*
 * Hauptschleife
 * Taste abfragen und solange gedrückt dimmen
 */
void loop( void )
{
  if(!digitalRead( tastenPin ) )  // Taste gedrückt?
    dimm( ledDimmPin );           // dann dimmen...
}

Etwas ausführlich vielleicht, aber ich hoffe man verstehts :o


Gruß
Peter
« Last Edit: May 10, 2009, 11:22:05 am by dh1ao » Logged

Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

 :o ok... schwere Kost... muss ich langsam verdauen
Logged

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So hab´s geschafft, hier die erste Ping-Pong Version, die beiden Arduinos senden sich abwechselnd Zufallswerte zu und blinken so oft mit der LED wie die empfangene Zahl. Ist noch etwas unelegant strukturiert aber der Wechseln ziwschen senden und empfange funktioniert, führt aber nach eineiger Zeit zu Dead-Lock weil beide warten und keiner mehr sendet.

Code:
#
/* PING-PONG V1 basierend auf:
#
 *  Nrf2401 library example 1 - RX
#
 *  March 2009 | jesse dot tane at gmail dot com
#
 *  geändert von Kimmi
#

#
 *
#
 */
#
 
#
#include "Nrf2401.h"
#
 
#
Nrf2401 Radio;
#
 
int forZaehler = 0;              // For Variable fuer die LED Blinkschleife
int forMax = 3;                 // For Variable fuer blink Anzahl
 
#
void setup(void)
#
{
#
  pinMode(13, OUTPUT);
#
  Radio.localAddress = 1;
#

  Radio.remoteAddress = 1; // von Sender
  
  
  Radio.rxMode(1);
#
}
#
 
#
void loop(void)
#
{
  
  
  // jetzt wird ersmal was gesendet //

  Radio.txMode(1);

      randomSeed(analogRead(5));       // leist den Analogpin 5 aus f?r Zufallrauschen //

      long randnum = random (1, 7);    // Zuf?llige Zahl zwischen 1 und 7
    
         Radio.data [0] = randnum;        // Zufallszahl gleich sende byte//

  Radio.write();
  
  // fertig mit senden //
  
  
  
  // jetzt gehe auf Empfang //
  
    Radio.rxMode(1);
#
  while(!Radio.available());
#
  Radio.read();
#


forMax = Radio.data[0];

for (forZaehler = 0; forZaehler < forMax; forZaehler++) { // Achtung hier kein ; am Ende !!!!

    digitalWrite(13, HIGH);
#
    delay(100);
#
    digitalWrite(13, LOW);
#

delay (100);

}
  
  

}

Würde das ganze gerne mit Funktionen schreiben damit ich das auf die Dauer übersichtlicher hinkriege. Die Funktionen muss ich nach C Syntax schreiben oder?
« Last Edit: May 10, 2009, 04:36:56 pm by oren » Logged

0
Offline Offline
Jr. Member
**
Karma: 2
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Kimmi

wird doch langsam! Schön dem Dinge....

Ich find gut, dass Du den Variablen Namen gibst, die symbolisieren wofür sie stehen (forZaehler, forMax...). Behalte das auf jeden Fall bei!!!
Je sprechender die Namen desto besser....

Du möchtest deinen Code strukturieren?! Genau richtig so!

Aber wie macht man das? Als Einsteiger gar nicht so einfach...

Was macht Dein Programm?

Es sendet zunächst eine Zufallszahlszahl. Sagen wir mal die Funktion heisst sendNumber. Dann soll das Programm auf eine Zahl eines anderen Teilnehmers warten receiveNumber. Zu guter Letzt soll die empfangene Zahl "ausgeblinkt" blink werden. Danach alles von vorn.

Also der Reihe der Reihe nach...
sendNumber soll einfach einen Zufallswert in die weite Welt senden. Einen Rückgabewert erwarten wir nicht.
Code:
void sendNumber( void )
{
   Radio.txMode(1);
   randomSeed(analogRead(5));
   Radio.data[0] = random(1,7);
   Radio.write();
}

So, nun haben wir eine Funktion, welche eine Zufallszahl sendet...

Jetzt brauchen wir eine Funktion, die diese Zufallszahl empfängt receiveNumber, Diese Funktion soll als Ergebnis die empfangene Zahl liefern

Code:
int receiveNumber( void )
{
   Radio.rxMode(1);
   while(!Radio.available());
   return Radio.read();
}

Jetzt fehlt nur noch das blinken blink der LED

Code:
void blink( int forMax )
{
int forZaehler;

  for( forZaehler=0; forZaehler<forMax; forZaehler++)
  {
     digitalWrite(13,HIGH);
     delay(100);
     digitalWrite(13,LOW);
     delay(100);
  }
}

Das war's auch schon. Wir haben jetzt 3 Funktionen
sendNumber
receiveNumber
blink

Damit können wir eine lustige loop Funktion übersichtlich basteln

Code:
void loop( void )
{
   int no;
   sendNumber();
   no = receiveNumber();
   blink( no );
}

Bisschen klarer geworden?

Viele Grüße
Peter
Logged

Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Super, werde es im Laufe des Tahes ausprobieren, sieht strukturiert auch viel schöner aus und auch besser kontrllierbar.

Danke Martin
Logged

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Peter sei Dank, der fertige Code:

Code:
// Arduinos senden sich Zufallszahlen zu und blinken dann die Zahl-mal //
// Peter sein Dank... der Rest ist von Martin //

#include "Nrf2401.h"

Nrf2401 Radio;


void setup () // Geht auch OHNE ADRESSIERUNG //

{
   pinMode(13, OUTPUT);
  
  }

void loop( void )
{
   int no;
   sendNumber();
   no = receiveNumber();
   blink( no );
}

void sendNumber( void )
{
   Radio.txMode(1);
   randomSeed(analogRead(5));
   Radio.data[0] = random(1,7);
   Radio.write();
}

int receiveNumber( void )
{
   Radio.rxMode(1);
   while(!Radio.available());
   Radio.read();
  [color=#ff0000] return Radio.data[0];[/color]
}

void blink( int forMax )
{
int forZaehler;

  for( forZaehler=0; forZaehler<forMax; forZaehler++)
  {
     digitalWrite(13,HIGH);
     delay(100);
     digitalWrite(13,LOW);
     delay(100);
  }
}


Zu beachten:

1) die Nrf240 Libraray muss in dem Ordner liegen in dem der Sketch ist

2) Hier wurde die Adressierung weggelassen, wer sie braucht muss sie ergänzen ( http://www.arduino.cc/playground/InterfacingWithHardware/Nrf2401) nach den dort aufgeführten Beispielen

3)   Radio.read(); ist ein Befehl, die Daten finden sich in
  return Radio.data[0];

4) auch dieses Programm belibt irgendwann stehen, wenn zufällig beide gleichzeitig auf Empfang landen - dies geschieht wenn der ein sendet während der andere noch blinkt und dieser deswegen den EMpfang des Signals verpasst
« Last Edit: May 11, 2009, 12:04:48 pm by oren » Logged

0
Offline Offline
Jr. Member
**
Karma: 2
Posts: 81
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Martin!

Das ist doch schon mal ne schöne Basis. Und richtig

Quote
return Radio.data[0];
Logisch...

Ich hab leider nur einen kleinen Arduino und so'n Stöpselboard. Vielleicht sollte ich mal mit meiner Heimleitung über ein Mega reden? Ne lieber nicht.  Hab in der letzten Zeit schon diverse Euronen versenkt in Elektronik.

Das mit dem Deadlock hab ich noch nicht ganz durchschaut.
Die beiden Arduinos können doch nur dann hängen bleiben, wenn keiner mehr sendet. Mit anderen Worten beide müßen in der "Todesschleife"
Code:
while(!Radio.available());
abchillen. Aber wie kann es dazu kommen? Bin absolut planlos  :-[

Aus der Beschreibung entnehme ich
Quote
Properties:

    * unsigned char data[NRF2401_BUFFER_SIZE];
          o An array that can store up to 25 bytes of incoming or outgoing data. The NRF2401_BUFFER_SIZE constant is 25 by default - open the header file if you want to change this.

das das Ding bis zu NRF2401_BUFFER_SIZE viele Zeichen zwischenspeichern kann.

Das sich die Jungs aufhängen sieht man ja, aber wieso? Kann es sein,
dass die Alemannen Arduino Forumsfront Internetverbot hat?

Wir bräuchten dann mal hier Unterstützung von nRF2401A Cracks!!!

Ich denk mal weiter drüber nach...


EDIT!!!
Quote
The Nrf2401 is a half-duplex transceiver, so while it has the ability to send and receive data, it cannot do both simultaneously

Könnte es das sein? Wenn beide gleichzeitig senden sind beide taub wie Brot. So quasi wie im Eheleben? Beide quatschen und keiner hört zu? Dann würde auch Radio.available() false liefern.... Möglein Möglein


Tschöööö
Peter
« Last Edit: May 11, 2009, 12:57:14 pm by dh1ao » Logged

Erkläre es mir, ich werde es vergessen. Zeige es mir, ich werde es vielleicht behalten. Lass es mich tun, und ich werde es können. Indisches

Darmstadt, Germany
Offline Offline
Full Member
***
Karma: 1
Posts: 141
Forum rocks ;o)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Peter, ich seh das so,

wenn der eine sendt wärend der andere noch mit der Blinkschleife beschäftigt ist, verpasst er den Empfang und wenn er dann fertig ist mit blinken und endlich auf Empfang geht, kommt nichts mehr, da der andere schon gesendet hat und dann sind sbeide auf Empfang und keiner sendet mehr. Dagegen wird normalerweise ein Watchdog-Timer eingesetzt, der nach eine bestimmten Zeit ohen Aktion einen Reset auslöst, ich weiß aber nicht ob das in Arduino umsetzbar ist.

Ich hab übrigens auch nur den normalen Duemillanove und Brotbrettchen :o) ... hab auch keinen Mega.

Ich fürchte übrigens WIR SIND die nRF240 Experten... hahahaaaaaaa
(Lachen kurz vor dem Wahnsinn  ;D  :smiley )

Mein Kumpel Ralph meinte ich sollte das ganze mit C-Klassen schreiben... HAHAHAAAAAAAAA (Lachen im Wahnsinn)
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 588
LumiNet rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
ich war ein paar Tage nicht aktiv im Forum unterwegs und hier hat sich viel getan. Ich habe den Anschluß verloren, läuft alles?  Jetzt scheint es nur noch grundsätzliche Software-Fragen zu geben, aber die Hardwareansteuerung läuft, richtig?

Ich glaube übrigens, dass die Boards nicht im DirectMode laufen und Du deswegen den DR Pin an einen Interrupt Pin hängen kannst.

Logged


Pages: 1 ... 3 4 [5] 6 7   Go Up
Jump to: