Go Down

Topic: Arduino und der Sparkfun Transceiver nRF2401A ??? (Read 7431 times) previous topic - next topic

kimmi

#75
May 12, 2009, 10:12 pm Last Edit: May 12, 2009, 10:20 pm by oren Reason: 1
Hallo Bohne,

woran sieht man denn in welchem Modus er läuft?

Stimmt, die Transceiver laufen jetzt auch wenn noch ein paar Unklarheiten bestehen, was wirklich in ihnen vorgeht - vorallem die "while" Schleife ist noch ein wenig rätslehaft -
heißt while(!Radio.available()); nicht, dass die Aktion bei "false" ausgeführt wird?


Hast du schon einen Termin für das Treffen?

bohne

while(!irgendwas)
{
tuewas
}
heisst: tuewas solange irgendwas nicht passiert.

Termin für Treffen habe ich noch nicht, aber mein Traum wäre der 13. Juni, denn dann geht STS-127 ins All und somit wäre die erste Arduino-"bemannte" Shuttlemission ein guter Termin für ein Arduino Treffen in Aachen inkl. open air Grill und Teleskop aufbauen. Wobei das Shuttle sieht man natürlich nicht, aber man könnte so tun. Vielleicht wäre ein Termin vor dem 13. Juni aber besser? Diskutieren wir besser im anderen Thread.
http://www.dorkbot.de
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236434254
http://www.luminet.cc

dh1ao

Hallo Martin und Bohne

die while Schleife ist eigentlich nicht das Problem. Ich gehe auch stark davon aus, dass wenn einer gerade blinkt und der andere sendet,dass dann  der Deadlock auftritt. Wenn dem so ist, ist entweder die Bibliothek oder die Hardware hmm sagen wir mal suboptimal.

Das würde ja im Umkehrschluss heissen, dass "wenn man nicht zur rechten Zeit (nämlich wenn der andere gerade sendet) am richtigen Ort (nämlich bei Radio.available()) ist man Zeichen verliert. Das glaube ich eig. nicht. Wofür wäre dann der Puffer mit 25 Zeichen der Bibliothek überhaupt gut?!

Ich hab da immer noch eher das Halbduplex im Verdacht...
Was sagt Du dazu Bohne? Ich hab leider nur einen Arduino und keinen Transceiver, daher alles bloß reine Theorie von mir...

Viele Grüße
Peter
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

kimmi

Hallo, der Transceiver sendet tatsächlich im Shockburst Mode, das kann man an den möglichen Übertragungsraten sehen. Damit ist es mgölich - oder es ist sogar der Fall - dass der Arduino über DR1 einen Interrupt erhält. Ich kann das in der Library nicht erkennen.

Ich frage mich immer noch ob es möglich ist gleichzeitig auf Empfang zu bleiben und andere Dinge zu tun... Eigentlich müsste das doch der Fall sein, wenn ich innerhalb des Loops den DR1 abfrage und dann erst das den Loop unterbreche und den rx-Mode aktiviere??

Nur..wo mache ich das?

kimmi

tue was solange nicht passiert

dann steht da doch im Programm:

solange Radio empfang NICHT möglich gehe auf Empfang

Aber das wäre doch total unsinnig ??

kimmi

#80
May 13, 2009, 12:08 am Last Edit: May 13, 2009, 12:43 am by oren Reason: 1
Quote
# bool available(void);

   * Calling this method will return a boolean value (true or false) depending on whether or not data is available to be read.

# void read(unsigned char* dataBuffer=0);

   * When data is available to be read, the DR1 pin on the radio hardware will go high. This can be detected by polling the with the "available()" method, or attaching an interrupt on digital pin 2 that looks for a rising edge. When you are sure data is ready to be read, calling this function will automatically download the available bytes into the "data" array property. Optionally, you can specify your own data array to download to as the first parameter.



Also ganz klar Shockburst Mode !

"Available" liest den DR1 aus und löst einen Interrupt aus und zwar wird der Empfang (!) unterbrochen, nachdem was gültiges reinkommt.



Quote
#
while(!Radio.available());
#
 Radio.read();


Das war mir bisher ein Rätsel aber jetzt versteh ich´s glaube ich:

Solange kein Singal zu empfangen ist, lausche weiter in den Äther -  sobald du was empfangen hast, höre auf mit lauschen und tu was


Ich hätte eher gedacht es müsste heißen:

Sobald du ein Signal empfängst, gehe auf Empfang....

aber anderherum geht`s wahrscheinlich besser, da verpasst man weniger.

Aber das bedeutet, ich kann nicht einfach andere Dinge tun und diese unterbrechen um auf Empfang zu gehen, es heißt leider andersherum, ich muss auf Empfang bleiben und kann nur andere Dinge tun, wenn ich etwas empfangen habe. Das ist schlecht.

kimmi

Ob es möglich ist eine Art Wecksignal vornedran zu schicken, dass nicht den eigentlichen Datenteil enthält und nur dazu dient "available" auf true zu setzen und dann erst auf Empfang zu gehen und nocn rechtzeitig zum Datenteil auf Empfang zu sein?

Quote
#
while(!Radio.available());
#
 Radio.read();


Das ! weglassen und die Logik umdrehen?

bohne

Das
Quote

while(!Radio.available());
#
 Radio.read();
#


steht ja im loop(), richtig?

somit wird die Hauptschleife aufgehalten, solange das radio nicht verfügbar ist. Sobald es jedoch verfügbar ist (etwa weil Daten angekommen sind), dann geht es weiter im Programm und es wird Radio.read() aufgerufen.

Das blockiert also die komplette CPU vom atmega. Die meiste Zeit verschwendet er mit warten.

Du kannst nun den DR Pin an einen interruptfähigen Arduino Pin anschließen und einen hardware interrupt auslösen lassen. Die Empfangsarbeit kannst Du dann in eine ISR auslagern. Ich denke aber mal, das alles sagt Dir nicht viel, oder?
Diese Schritte sind auch nicht unbedingt notwendig, denn wenn es in der loop() so funktioniert wie es jetzt ist, dann ist es ja gut. Ich bin leider nicht ganz auf dem Stand der Dinge, was Dir noch fehlt und was aktuell der Code ist...

und nochmal zu der while Schleife:

while(!erloesendesEvent);

ist das gleiche wie

while(!erloesendesEvent)
{
//tue garnix
}

die Klammern können dann also weggelassen werden und die while Schleife blockiert einfach nur bis die Abbruchbedingung (erloesendesEvent) eintritt.
http://www.dorkbot.de
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236434254
http://www.luminet.cc

kimmi

Hallo Bohne,

ich möchte aber ein paar Dinge erldigen während ich auf Signale warte !

NOchmal zu der while.. das ! bedeutet doch in diesem Falle, dass das Event bei "false" stattfindet oder? Also wenn Radio.availabe = false gehe auf Empfang oder? Das wundert mich ein wenig.

Besitzt dr Arduino überhaupt einen Hardware Interrupt? Und ist das nicht gleichbedeutend mit einem Reset? Kann cih festlegen wo er im Programm nach einem Hardware INterrput weitermacht?

kimmi

So jetzt auch zum Senden von Sensorwerten:

Code: [Select]
// Arduinos senden sich Sensorwerte 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);
 
 int value = 0;                            // variable to keep the actual value

 int wertHELL = 0;
 
 }




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

void sendNumber( void )
{
 delay (600); // warte vor dem senden falls der andere noch am blinken ist und noch nicht auf Empfang //
 int wertHELL = 0;
  Radio.txMode(1);
  wertHELL = analogRead (0) / 20;
  Radio.data[0] = wertHELL;
  Radio.write();
}

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

void blink( int forMax )
{
int forZaehler;

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


}


Sensorwerte hab ich auf ein Zehntel runtergerechnet um sie in einem byte unterzugringen.

Weiß jemand ob ich auch mehr als ein byte senden kann oder andersherum gefragt, wenn ich Werte über 256 senden möchte, wie mach ich dass dann? Ich kann ja pro Radio.data (x) nur ein byte senden.

Code: [Select]
#
Radio.txMode(3);
#
 Radio.data[0] = 22;
#
 Radio.data[1] = 33;
#
 Radio.data[2] = 44;


Ich kann so zwar mehrere bytes hintereinander schicken aber wie mach stelle ich da zum Beispiel 467 dar?

kimmi

Wie es scheint bleibt der Transceiver hängen wenn er im Supershockburst-Mode mit 1mbit betrieben wird, nachdem ich ihn in den lahmen 25kbit Shockburst-Mode versetzt habe läuft er durch.

kimmi

Bisherige Fakten:

- Anschluß und Library aus Playground benutzen, funktioniert gut

- Reichweite in Räumen nur Sichtlinie und durch Glas, keine Wände
 (gilt für Keramikantenne)

- der Transceiver sendet im Shock-Burst Modus aber nur der 250kbit Modus ist zuverlässig - muss man in Nrf2401.cpp ändern
Code: [Select]
dataRate = 0; // 1 für 1mbit, 0 für 25okbit - 0 ist zuverlässiger !!! //

- der DR1 Pin des Transceiver (an Pin2 Arduino) zieht hoch wenn ein Signal eintrifft, der Transceiver muss dann voher schon auf Empfang sein, sonst verpasst er wahrscheinlich auch den Rest des Signals


Ungeklärt:

- wie kann ich andere Dinge tun und gleichzitig auf Empfang bleiben ?

- wie sende ich Zahlen, die größer 256 sind ?

- wie viel besser sind die Module mit anderen Antennen ?

- wie lange läuft das Ding mit Batterien

bohne

#87
May 14, 2009, 12:20 pm Last Edit: May 14, 2009, 12:22 pm by bohne Reason: 1
Quote

NOchmal zu der while.. das ! bedeutet doch in diesem Falle, dass das Event bei "false" stattfindet oder? Also wenn Radio.availabe = false gehe auf Empfang oder? Das wundert mich ein wenig.

es heist: warte solange NICHT Radio.available. Also tue nichts, solange Radio nicht verfuegbar ist. Das ist also von der Logik her richtig herum formuliert.
Die Schleife soll ja solange blockieren bis !Radio.available false wird.
Es gibt ja nur diese beiden Faelle:
1. Radio.available = false bedeutet also: !Radio.available = true und somit wird die while Schleife NICHT verlassen, der Prozessor verbleibt in der Warteschleife. ( while(!Radio.available) ist ja in diesem Fall while(true))

2. Radio.available = true bedeutet also: !Radio.available = false und somit wird die while Schleife verlassen, die Warterei hat ein Ende. ( while(!Radio.available) ist ja in diesem Fall while(false))

Quote

Besitzt dr Arduino überhaupt einen Hardware Interrupt? Und ist das nicht gleichbedeutend mit einem Reset? Kann cih festlegen wo er im Programm nach einem Hardware INterrput weitermacht?

Der Arduino hat so viele Interrupts wie der auf ihm verwendete Atmel ATMega 168 Chip. Dieser hat eine ganze Fuelle an Interrrupts. Interessant sind die hardware interrupts. Um das ganze in der Arduino Syntax zu implementieren kannst Du Dir diese Seite mal angucken:
http://arduino.cc/en/Reference/AttachInterrupt

Man kann das auch in der normalen AVR C Syntax machen, siehe etwa hier (handelt sich nicht um externen hardware interrupt, sondern um timer, aber immerhin):
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236866849
und so machen es andere:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241920539/2
http://www.dorkbot.de
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236434254
http://www.luminet.cc

dh1ao

Hallo Bohne

ich Martin mal ein Beispiel mit dieser Timer2 Bibliothek gepostet. Aber wie Martin schon schrieb, schwere Kost.

Viele Grüße
Peter
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

kimmi

Diese while Logik war ein wenig evrwirrend, im ENdeffekt bedeutet das aber dann, dass ich einfach den DR1 Pin über "availabel" auf eingehnde Nachrichten hin überprüfen kann und dann erst auf Empfang gehe.

Da ein byte bei 1mbit ca 1 1/1000stel Sekunde lang ist un der Arduino mit 16.000 hz läuft müsste er genug durchgänge schaffen um jedes Signal zu erwischen.

Ich werde es ausprobiren und dann bescheid sagen.

Go Up