Forum: Mikrocontroller und Digitale Elektronik Arduino schnelle Datenübertragung mit 2Mbit/s


von Klaus H. (star_wars45) Flattr this


Lesenswert?

HI Leute,

ich bin ein absoluter Arduino Anfänger und bräuchte jetzt eure Hilfe.
Mit C, habe ich ein bisschen im laufe meines Studiums programmiert, aber
ist schon etwas her.

Ich habe 2 Arduinos einmal den Uno und den Due. Der Due soll mit einem 
Funkmodul (nrf24l01) Daten an den Uno senden. Der Empfänger soll diese 
Daten dann an einem LCD anzeigen. Nun soll die ganze Sache aber mit 2 
Mbit/s Übertragungsrate erfolgen.

Wie kann überhaupt die Übertragungsrate sehen oder testen ?

Ich habe erst versucht, die Daten zu senden und zu empfangen. Das habe 
ich auch schon hinbekommen.

Was muss ich am Code verändern oder ergänzen, damit die Daten schneller 
gesendet werden können ?

Unten sieht ihr den Sendercode. Ich weiß nicht mehr weiter und ich 
hoffe, ihr könnt mir weiter helfen.


Vielen Dank schon mal im voraus.

SENDER:

#include <SPI.h>                            //Aufruf der SPI Library
#include <nRF24L01p.h>
#include <regMapCmds.h>

nRF24L01p transmitter(7,8);                 // Funkmodul mit Pin 7 CSn 
und Pin 8 CE einstellen


#define MISO 74      //definiere MISO als Pin 74
#define SCLK 76      //definiere SCLK als Pin 76

unsigned int uibyte1;   //byte1 mit 8Bit
unsigned int uibyte2;   //byte2 mit 8Bit
unsigned int uibyte3;   //byte3 mit 8Bit
                        // 3*8Bit = 24Bit

float xx =0.0;
float xy =0.0;
float wert=0.0;
float wert2=0.0;


String message;

void setup()
{

 pinMode(SCLK, OUTPUT); // legt Pin SCLK als Ausgang fest
 pinMode(MISO, INPUT);  // legt Pin MISO als Eingang fest
 pinMode(1, OUTPUT);

 resette_adc();      // Springe in Funktion resette_adc


 SPI.begin();
 SPI.setBitOrder(MSBFIRST);             //Most significant Bit zuerst
 SPI.setClockDivider(SPI_CLOCK_DIV4);   //Teilt 16MHz durch 8 und gibt 
als
                                          SCLK 2MHz aus
 SPI.setDataMode(SPI_MODE0);            //SPI Modus CPOL=0, CPAH=0
 digitalWrite(SCLK, LOW);
 digitalWrite(MISO, LOW);



 transmitter.channel(90);                //Senderkanal 90
 transmitter.TXaddress("KUADA");         //Name des Empfängers
 transmitter.init();                     //Funkmodul wird initialisiert

}

void loop()                        //Normalerweise die eigentlich 
Hauptfunktion
{
 if (digitalRead(MISO) == HIGH) lese_ad();     // Wenn MISO Pin HIGH ist
                                                  gehe zu Funktion 
lese_ad
}
void resette_adc()              //Funktion zum AD-Wandler Reset,
{                               //dazu muss die SCKL auf HIGH
 digitalWrite(SCLK, HIGH);      // für mindestens 4 Wandlungszyklen sein
 delayMicroseconds(120);        // Ein Wandlungszyklus = 24µs
}


void lese_ad()
{
 DRDY_MODUS();                  //Springe in Funktion  DRDY_MODUS

 uibyte1 = SPI.transfer(0x00);   //lese byte1   MSB
 uibyte2 = SPI.transfer(0x00);   //lese byte2
 uibyte3 = SPI.transfer(0x00);   //lese byte3   LSB


for(int i=0;i<25;i++){          //Berechnung der Durchschnittswerts 
aufgrund von Wandlerschwankungen
    xx+=(uibyte1<<16 | uibyte2<<8 | uibyte3); //Einlesen der Bytes mit 
Bitverschiebung in korrekte Position
    }
    xx=trunc(xx/25);

xy = (5.0/65536.0);                        //Bereichsbreite 16bit

if (uibyte1 == 255)                          //MSB = HIGH
{
wert2 = ((xx *xy)-1.77250);            // Der AD-Wandler Wert (Spannung)
wert = wert2 -5.00;
  message = "HIGH  ";
  message +=wert;
  transmitter.txPL(message );       //AUSGABE
  transmitter.send(SLOW);
  digitalWrite(1, HIGH);
  delay(250);
}
else
{
wert = ((xx *xy)-1.77250);           // Der AD-Wandler Wert (Spannung)

   message = "LOW  ";
   message +=wert ;
   transmitter.txPL(message);       //AUSGABE
   transmitter.send(SLOW);
   digitalWrite(1, HIGH);
   delay(250);
}
}


void DRDY_MODUS()                    //  Funktion für den Data Ready 
Modus.
{                                    //  Zeigt alle 24µs an, dass neue 
Daten zum lesen bereit stehen
  delayMicroseconds(2.25);           //  Immer zu Beginn vom 
Wandlungszyklus, nach Ablauf können Daten gelesen werden
}                                    //  t4 = 1,5µs HIGH + t2 = 375ns 
LOW       t3 = 375ns

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Man moege mich korrigieren wenn ich falsch liege, aber mit dem NRF24l01 
wirst du mMn niemals die 2Mbit/s dauerhaft schaffen.

von pi (Gast)


Lesenswert?

die 2MBit/s sind die absolute maximal rate die das NRF kann ...aber 
willkommen in der welt vom funk. Wenn die Datenrate wichtig is und du 
diese unbedingt brauchst: Nimm Kabel.

von Klaus H. (star_wars45) Flattr this


Lesenswert?

Es muss nicht unbedingt die 2 Mbit/s erreicht werden, aber es sollte 
schon  alles rausgeholt werden was der NRF übertragen kann


@Autor: pi (Gast)

Da es in einem rotierenden System integriert wird, muss es über 
Funkmodul sein.

von Kai S. (kai1986)


Lesenswert?

Ibrahim Hakikat schrieb:
> Was muss ich am Code verändern oder ergänzen, damit die Daten schneller
> gesendet werden können ?

Wenn der Code schnell sein soll haben delays darin nichts zu suchen, 
dafür gibt es Interrupts und Timer. Auch den ADC jedes mal zu resetten 
nicht klug.

Und allgemein gilt, wenn es schnell werden soll nimmt man C, soll es 
noch schneller werden Assembler.

Gruß Kai

von Seano L. (Gast)


Lesenswert?

Man müsste erst mal wissen wie deine lib den nrf anspricht.

Je nachdem mit welchen Einstellungen man den nRF betreibt kommt man gar 
nicht erst ran an die 2MBit/s selbst wenn dein Controller schnell genug 
ist.

Das drumherum sieht ja schon performancevernichtend aus,
da sehe ich erst mal schwarz mit 2MBit/s.

Zudem ist die Frage was der Empfänger mit den Daten macht, einfach nur 
wegspeichern wenn ja wohin und wie, wird noch mit den Daten 
rumgerechnet,...

"Es kommt darauf an..."

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

@ Ibrahim Hakikat (Firma: Continental) (star_wars45)

>Daten dann an einem LCD anzeigen. Nun soll die ganze Sache aber mit 2
>Mbit/s Übertragungsrate erfolgen.

Wie bereits gesagt ist das mit der Geschwindigkeit nicht sooo einfach.

>Wie kann überhaupt die Übertragungsrate sehen oder testen ?

Mit einem passenden Messgerät. Zur Not kann oder muss man das mit etwas 
Grips in seinem eigenen Code messen. Dazu kann man einen Timer 
verwenden. Den gibt es sogar schon beim Arduino-Framework, siehe 
Funktion millis().

http://www.arduino.cc/en/Reference/Millis

Wenn man nun bei jedem Durchlauf die Zeitdifferenz zum letzten mal mißt, 
weiß man, wie lange ein loop() Durchlauf braucht. Oder man misst die 
Zeitdifferenz für 1000 Durchläufe, geht auch. Alles ohne zusätzliche 
Messgeräte.

>Ich habe erst versucht, die Daten zu senden und zu empfangen. Das habe
>ich auch schon hinbekommen.

Also von irgendwo einen Beispielcode kopiert und es hat zufällig 
funktioniert?

>Was muss ich am Code verändern oder ergänzen, damit die Daten schneller
>gesendet werden können ?

Weißt du überhaupt, was dein Code macht? Und warum?

>Unten sieht ihr den Sendercode. Ich weiß nicht mehr weiter und ich
>hoffe, ihr könnt mir weiter helfen.

Ja, lies mal was über Netiquette. Längere Quelltexte schickt man als 
Anhang.

Alles in allem ist das nicht unbedingt eine Anfängeraufgabe. U.a. kannst 
du problemlos davon ausgehen, dass diese Zeit nicht stimmt, die Funktion 
arbeitet mit Ganzzahlen.
1
    delayMicroseconds(2.25);            //  Immer zu Beginn vom Wandlungszyklus, nach Ablauf können Daten gelesen werden
2
}                                       //  t4 = 1,5µs HIGH + t2 = 375ns LOW       t3 = 375ns

Ausserdem ist die Struktur deines (kopierten?) Programms schlecht, denn 
du vermischt viele Aufgaben, wie das Auslesen des ADC und das Versenden 
der Nachricht. Über das Thema Mittelwertbildung solltest du nochmal 
nachdenken ;-)

: Bearbeitet durch User
von Karl (Gast)


Lesenswert?

Ibrahim Hakikat schrieb:
> Ich habe 2 Arduinos einmal den Uno und den Due. Der Due soll mit einem
> Funkmodul (nrf24l01) Daten an den Uno senden. Der Empfänger soll diese
> Daten dann an einem LCD anzeigen. Nun soll die ganze Sache aber mit 2
> Mbit/s Übertragungsrate erfolgen.

2 Mbit/s und "Daten dann an einem LCD anzeigen" passt irgendwie nicht 
zusammen. Das menschliche Auge arbeite bis etwa 10 Hz danach kommt nur 
noch flimmern. An einem LCD kannst du vielleicht 1 mal pro Sekunde zwei 
Zahlenwerte (16 bit) ausgeben. Alles andere ist sinnlos. Das macht 16 * 
2 * 10 = 320 Bits/s netto.

Und überleg mal, du willst mit einem 16 MHz Prozessor 2 Mbit/s 
verarbeiten, d.h. du hast 8 Takte pro Bit oder 64 pro Byte. Bist du dir 
sicher, das du das so programmieren kannst?

Klaus H. schrieb:
> Es muss nicht unbedingt die 2 Mbit/s erreicht werden, aber es sollte
> schon  alles rausgeholt werden was der NRF übertragen kann

Überleg dir was du brauchst. Anstatt mehr Bandbreite könnte man auch mal 
über die Reduzierung der Daten nachdenken.

> @Autor: pi (Gast)
>
> Da es in einem rotierenden System integriert wird, muss es über
> Funkmodul sein.

Es gibt auch Schleifringe.

Schreib was du machen willst, wahrscheinlich gibt es bessere 
Lösungsansätze.

von Falk B. (falk)


Lesenswert?

@ Karl (Gast)

>> Da es in einem rotierenden System integriert wird, muss es über
>> Funkmodul sein.

>Es gibt auch Schleifringe.

Und kontaktlose Schleifringe ;-)

https://www.mikrocontroller.net/articles/Royer_Converter#Weblinks

http://www.schleifring.de/de/Produkte/Technologien/Kontaktlose._.Uebertragung/energie.uebertragung.php

>Schreib was du machen willst, wahrscheinlich gibt es bessere
>Lösungsansätze.

Das ist, wie so oft, die sinnvollste Frage.

von Pandur S. (jetztnicht)


Lesenswert?

Wenn das ganze asynchron per UART uebertragen werden muss, muss das UART 
fuer 2MBit wegen oversampling mit mind. 16MHz laufen. und dann bekommt 
man 200k-interrupts pro sekunde. Viel mehr geschiht dann daneben auch 
nicht mehr. Daher was soll das Ganze. Scheint ein Furz zu sein.

von Falk B. (falk)


Lesenswert?

@Jetzt Nicht (jetztnicht)

>nicht mehr. Daher was soll das Ganze. Scheint ein Furz zu sein.

Ist es auch ;-)

von Falk B. (falk)


Lesenswert?

@ Klaus H. (star_wars45)

Warum ändern die Leute immer wieder ihren Namen im Forum? Kann man sich 
da nicht beim ersten Mal in einer ruhigen Minute festlegen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.