Arduino bits Übertragen

Hallo Leute,
Ich müsste ca. 50Bits bei einer bitlänge von 10ms über einen arduino kontinuierlich übertragen.
Ich habe einen sehr langen code geschrieben( mit delay zwischen high und low).
Ich frage mich jedoch, ob es eine bessere Methode gibt, die bits zu senden.
Ich bin da leider nicht so der hellste, wenn es um vereinfachen geht.
Kann mir jemand einen Tipp geben?

SPI ?!?

Timer ISR ?!?

Delay ist böse.

Du könntest den Code posten. Mach ihn vorher ein bisschen hübsch.

Gruß

Gregor

combie:
SPI ?!?

Timer ISR ?!?

Sorry, aber mir scheint, dass die genannten Begriffe recht schwierig zu verstehen sind.

Fällt dir nicht etwas einfacheres ein? Hätte gedacht es gäbe eine Funktion.
Soll ja nur 1010110000110011000 auf pin 4 mit 10ms bitzeit senden..

gregorss:
Delay ist böse.

Du könntest den Code posten. Mach ihn vorher ein bisschen hübsch.

Gruß

Gregor

Ich würde das Prinzip doch recht gern verstehen, da ich dort sowieso nicht drumherum komme.

Elcoapon:
Ich würde das Prinzip doch recht gern verstehen, da ich dort sowieso nicht drumherum komme.

Um delay() herum zu kommen ist nicht allzu schwierig. Vielleicht hilft Dir mein Geschreibsel.

Gruß

Gregor

Ich müsste ca. 50Bits bei einer bitlänge von 10ms über einen arduino kontinuierlich übertragen.

Was heisst “kontinuierlich” Was heisst “übertragen”?
Was soll danach passieren?
Wie genau müssen die 10 ms sein?

const byte out = LED_BUILTIN;

const byte data [] = {  B10110011,
                        B10001111,
                        B00001111,
                        B10000011,
                        B11110000,
                        B00111111,
                        B10000000 
                     }; // 50 (bis 56) Bit: Ausgabereihenfolge von links nach rechts, dann nach unten 


void send(bool bit) {
// Mit simpler Zeitsteuerung 
   digitalWrite(out, bit);
   delay(10); 
}

void loop() {}

// Test: Nach Reset wird die Sequenz einmal auf Pin 13 ausgegeben,
//          danach bleibt die LED aus 

void setup() {
   pinMode (out, OUTPUT);
   for (byte i = 0 ; i < sizeof(data); i++)
       for (byte bit = 0x80; bit != 0 ; bit >>=1)
          send ( data[i] & bit );
}

Ist das ein langer Sketch ?

Sorry, aber mir scheint, dass die genannten Begriffe recht schwierig zu verstehen sind.

Fällt dir nicht etwas einfacheres ein?

Nein.
Das verstehen kann ich dir nicht abnehmen.
Danach ist es einfach.

Hätte gedacht es gäbe eine Funktion.

Wenn eine gibt, findet man sie in der Dokumentation (so Gott will)
Wenn es keine gibt, schreibt man sich eine (das nennt man dann programmieren)

Soll ja nur 1010110000110011000 auf pin 4 mit 10ms bitzeit senden..

Da sehe ich keine 50 Bit.

Hallo
Du könntest deine Bits in einer Zeichenkette hinterlegen und dann über einen Index auf jedes einzelne Zeichen zugreifen und es ausgeben.
Die Ausgabe machst du mit millis dann in deinem gewünschten Zeitaster.

Compiled aber ungetestet.
LSB shiftout mit 10ms Bitzeit, gibt momentan nur feste Vielfache von 8 Bits aus, das muss aber nicht stören.

const byte outPin = 4;
const unsigned long bitDuration = 10000;

byte dataToSend[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0x02 };
byte currentByte;
byte currentBit;
bool active;
unsigned long lastBitStarted;

void oneShot() {
  if (!active) {
    currentByte = 0;
    currentBit = 0;
    active = true;
    digitalWrite(outPin, dataToSend[currentByte] & (1 << currentBit));
    lastBitStarted = micros();
  }
}

void setup() {
  pinMode(outPin, OUTPUT);
  oneShot();
}

void loop() {
  unsigned long topLoop = micros();
  if (active && topLoop - lastBitStarted >= bitDuration) {
    if (++currentBit >= 7) {
      currentBit = 0;
      if (++currentByte >= sizeof(dataToSend)) {
        currentByte = 0;
        active = false;
      }
    }
    if (active) {
      digitalWrite(outPin, dataToSend[currentByte] & (1 << currentBit));
    }
    lastBitStarted = topLoop;
  }
}

Whandall:
Compiled aber ungetestet.
LSB shiftout mit 10ms Bitzeit, gibt momentan nur feste Vielfache von 8 Bits aus, das muss aber nicht stören.

const byte outPin = 4;

const unsigned long bitDuration = 10000;

byte dataToSend = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0x02 };
byte currentByte;
byte currentBit;
bool active;
unsigned long lastBitStarted;

void oneShot() {
 if (!active) {
   currentByte = 0;
   currentBit = 0;
   active = true;
   digitalWrite(outPin, dataToSend[currentByte] & (1 << currentBit));
   lastBitStarted = micros();
 }
}

void setup() {
 pinMode(outPin, OUTPUT);
 oneShot();
}

void loop() {
 unsigned long topLoop = micros();
 if (active && topLoop - lastBitStarted >= bitDuration) {
   if (++currentBit >= 7) {
     currentBit = 0;
     if (++currentByte >= sizeof(dataToSend)) {
       currentByte = 0;
       active = false;
     }
   }
   if (active) {
     digitalWrite(outPin, dataToSend[currentByte] & (1 << currentBit));
   }
   lastBitStarted = topLoop;
 }
}

Banhhoff!!!

Wie würde das mit diesem code aussehen? In den Kommentaren steht die Bitfolge. (i=1, o=0)

void besetzt(){
 o();o();o();o();o();o();o();o();o();o();                    //10x0
 i();i();i();i();i();i();i();i();i();i();i();i();i();i();    //14x1
 o();o();i();o();i();o();o();o();o();o();                    //0010100000
 i();i();i();i();i();i();i();i();i();i();i();i();i();i();    //14x1
 o();i();o();o();i();o();i();o();i();o();                    //0100101010
 i();i();i();i();i();i();i();i();i();i();i();i();i();i();    //14x1
 }

void unbesetzt(){
         o();o();o();o();o();o();o();o();o();o();                    //10x0
         i();i();i();i();i();i();i();i();i();i();i();i();i();i();    //14x1
         o();o();i();o();o();o();o();o();i();                        // 001000001
         i();i();i();i();i();i();i();i();i();i();i();i();i();i();    //14x1
         o();i();o();o();i();o();o();o();o();o();                    //0100100000
         i();i();i();i();i();i();i();i();i();i();i();i();i();i();    //14x1
 }
byte dataToSend[] = { 0x00, 0x3F, 0xFF, 0x28, 0x3F, 0xFF, 0x4A, 0xBF, 0xFF };

sollte

000000000011111111111111001010000011111111111111010010101011111111111111

0000 0000  0011 1111  1111 1111  0010 1000  0011 1111  1111 1111  0100 1010  1011 1111  1111 1111

entsprechen.

Warum ist dein zweiter Kode ein Bit kürzer?

Dir ist schon bewusst dass 72 nicht "ca. 50Bits" sind?

Hi

DAS ist der zu sendende Code:

byte dataToSend[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0x02 };

0x kennzeichnet dabei eine Hexadezimal-Zahl
A = 10, besteht aus 8 und 2
1010 1010 (A A)
0101 0101 (5 5)
0101 1010 (5 A)
0001 0010 (1 2)

Die Wertigkeit ist pro Buchstabe (Nibble) von Rechts nach Links 1,2,4,8.
Du kannst statt Hexadezimal auch Octal benutzen - dort ist die Basis 8 (bei Hex 16).
Diese Zahlen werden mit vorgestellter Null gekennzeichnet:
041 → 4 8er, 1 1er → 33Dez

Und dann gibt’s noch Binär - hier ist die Basis 2, der Ziffernvorrat erstreckt sich über 0 und 1.
Wenn man jetzt statt 0 und 1 o und i schreibt - könntest Du Dir Deine Bitfolge selber zusammen stückeln:
uint64_t bitmuster=0b00000000 0011111 1111111 1100101 0000011 1111111 1111101 0010101;// 01111111 1111111_;
… könnte aber sein, daß 72 ‘Ziffern’ etwas zu viel - man kann Das aber in zwei Zahlen aufteilen und Diese dann versenden - nicht genutzte Bits werden dort dann wohl als LOW übertragen.

MfG

postmaster-ino:
Hi

DAS ist der zu sendende Code:

byte dataToSend[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0x02 };

0x kennzeichnet dabei eine Hexadezimal-Zahl
A = 10, besteht aus 8 und 2
1010 1010 (A A)
0101 0101 (5 5)
0101 1010 (5 A)
0001 0010 (1 2)
...
Die Wertigkeit ist pro Buchstabe (Nibble) von Rechts nach Links 1,2,4,8.
Du kannst statt Hexadezimal auch Octal benutzen - dort ist die Basis 8 (bei Hex 16).
Diese Zahlen werden mit vorgestellter Null gekennzeichnet:
041 -> 4 8er, 1 1er -> 33Dez

Und dann gibt's noch Binär - hier ist die Basis 2, der Ziffernvorrat erstreckt sich über 0 und 1.
Wenn man jetzt statt 0 und 1 o und i schreibt - könntest Du Dir Deine Bitfolge selber zusammen stückeln:
uint64_t bitmuster=0b00000000 0011111 1111111 1100101 0000011 1111111 1111101 0010101;// 01111111 1111111_;
... könnte aber sein, daß 72 'Ziffern' etwas zu viel - man kann Das aber in zwei Zahlen aufteilen und Diese dann versenden - nicht genutzte Bits werden dort dann wohl als LOW übertragen.

MfG

was bedeutet denn dieses "0x" ? ich meine Hexa und Okta ist mir bekannt. Nur das nachvollziehen, dass er die null als LOW ausgibt ist mir noch etwas schleierhaft.

Elcoapon:
was bedeutet denn dieses "0x" ? ich meine Hexa und Okta ist mir bekannt.

Wenn es das wirklich wäre, dann wäre Dir auch die 0x-Schreibweise bekannt, mit der man dem Kompiler bekannt gibt, dass man eine Hexadezimale Zahl angeben will. Es gibt auch Schreibweisen für oktal und binär.

Gruß Tommy

Tommy56:
Wenn es das wirklich wäre, dann wäre Dir auch die 0x-Schreibweise bekannt, mit der man dem Kompiler bekannt gibt, dass man eine Hexadezimale Zahl angeben will. Es gibt auch Schreibweisen für oktal und binär.

Gruß Tommy

Nunja, bekannt dass nach 7 eine 10 kommt im Okta. Genauso wie das Dividieren sowie addieren von Dezimal und Hex.
Nur leider nicht in der Programmiersprache..

Nochmal, warum ist dein zweiter Kode ein Bit kürzer?

Kodes welcher Länge willst du verschicken können?

Was willst du überhaupt machen?

Hier würde sich natürlich eine Klasse eignen das Shiften nicht blockierend zu implementieren.

const byte outPin = 4;
const unsigned long bitDuration = 10000;

class Shifter {
    byte pin;
    unsigned long dauer;
    const byte* was;
    byte bits;
    byte currentBit;
    bool active;
    unsigned long lastBitStarted;
  public:
    Shifter(byte iPin, unsigned long iDuration) :
      pin(iPin), dauer(iDuration),
      was(nullptr), bits(0), currentBit(0), active(false), lastBitStarted(0) {}
    void begin() {
      pinMode(pin, OUTPUT);
    }
    void emit(const byte *data, byte anzahlBits) {
      if (!active) {
        was = data;
        bits = anzahlBits;
        if (bits) {
          currentBit = 0;
          digitalWrite(outPin, bitRead(*was, 7 - currentBit));
          lastBitStarted = micros();
          active = true;
        }
      }
    }
    void run() {
      if (active) {
        unsigned long topLoop = micros();
        if (topLoop - lastBitStarted >= bitDuration) {
          if (!--bits) {
            active = false;
          } else {
            if (++currentBit >= 7) {
              currentBit = 0;
              was++;
            }
            digitalWrite(outPin, bitRead(*was, 7 - currentBit));
            lastBitStarted = topLoop;
          }
        }
      }
    }
} sender(outPin, bitDuration);

byte dataToSend[] = { 0x00, 0x3F, 0xFF, 0x28, 0x3F, 0xFF, 0x4A, 0xBF, 0xFF };

void setup() {
  sender.begin();
  sender.emit(dataToSend, 72);
}

void loop() {
  sender.run();
}

Mein arduino Pro mini sendet das Signal mit diesem code nur 1x. Wollte dass es ohne Unterbrechung das gleiche Signal sendet.

Wieso das 72 und 73 bits sind, kann ich dir nicht sagen, die sind einfach da. Ich mache das ganze um ein Lüftersteuergerät(Mit Motor) von einem Auto als Antrieb für ein Fahrrad nutzen.
Um jedoch die Stromaufnahme regeln zu können braucht das Steuergerät immer wieder diese 2 Signale, damit es losgehen kann.

Elcoapon:
Mein arduino Pro mini sendet das Signal mit diesem code nur 1x.

Das ist als Minimalbeispiel absichtlich so. Und etwas sollte doch auch noch für dich zu tun bleiben. :wink:

begin muss da bleiben wo es ist, run muss frei laufen.

emit startet eine Übertragung, ändert man während der Übertragung die zu übertragenden Daten
könnte spannend werden was wirklich übertragen wird.
Im Beispiel ist das ja ein konstanter Array, da ändert sich nichts.

Wie oft du eine neue Sequenz startest und mit welchen Daten ist egal, wenn sich Übertragungen überlappen,
wird die erste augenblicklich abgewürgt.
(Sieh das als Hinweis dass eine einfache Verschiebung des emit von setup nach loop nicht funktioniert.)

Elcoapon:
Mein arduino Pro mini sendet das Signal mit diesem code nur 1x.

Ein benötigtes Signal auf der Zielhardware mit wartbarem Code ist doch schon gut.

Elcoapon:
Wollte dass es ohne Unterbrechung das gleiche Signal sendet.

widerspricht

Elcoapon:
braucht das Steuergerät immer wieder diese 2 Signale, damit es losgehen kann.

Elcoapon:
Ich mache das ganze um ein Lüftersteuergerät(Mit Motor) von einem Auto als Antrieb für ein Fahrrad nutzen.

Hast du ein Datenblatt, Link, gnaue Typenbezeichnung, oder irgendwas von dem Teil?
Auto wäre doch meistens CAN, oder?