8 Bit zu 16 Bit Fehler in der Zusammenführung

Gast #4905361
Hallo,

Ich versuche aus zwei 8 Bit einen 16 Bit Wert zu einem PCA9685 zu 
Senden.


Leider bin ich nicht der C Profi und hoffe daher auf etwas Unterstützung 
oder Ratschläge.



Hier einmal mein versuch
1
while(1) {  
2
 if(dmx_rx_complete) {
3
      uint8_t led = 0;
4
      for(led = 0; led < 16; led++) {
5
        pca9685_led_pwm(PCA9685_CHIP_1, led_map[led], (dmx_buf_back[led + 1] << 8 ) | dmx_buf_back[led + 2]);
6
        
7
            }
8
         }
LG
Sven
Gast
Wenn dmx_buf_back 8 bit breit ist, dann wird das Geschiebe dazu führen, 
dass leuter nullen drin stehen.

Mach dir vorher einen Helper

unsigned int uihelper; //(16 Bit)

uihelper = (dmx_buf_back[led + 1] << 8 ) | (dmx_buf_back[led + 2]);

Bin mir nicht sicher, aber vielleicht musst du auf der rechten Seite 
auch noch ein Cast machen, damit dort überhaupt mit 16 bit gerechnet 
wird:

uihelper = (unsigned int)(dmx_buf_back[led + 1] << 8 ) | 
(dmx_buf_back[led + 2]);

Werner
Gast
Werner schrieb:
> Wenn dmx_buf_back 8 bit breit ist, dann wird das Geschiebe dazu führen,
> dass leuter nullen drin stehen.

nein, C legt fest das alles mindestens in int (16 bit) rechnet wird.


@ShishaLiVe
was geht dann nicht? Was kommt raus und was erwartest du?
Gast
Dein Code ist mit Sicherheit falsch, da Du led+1 und led+2 verpackst und 
dann in der Schleife led++ machst.

Beschreibe erstmal, was im letzten Parameter drinstehen soll, dann 
können wir sagen, wie es geht. Und beschreibe, ob das höchstwertige byte 
zu Anfang oder am Ende steht (in einem Array bei 0 oder bei 1?)

Vielleicht wolltest Du sowas:
1
if(dmx_rx_complete) 
2
{
3
uint8_t led = 0;
4

5
   for(led = 0; led < 16; led++) 
6
   {
7
   uint16_t v = dmx_buf_back[led*2 + 1] << 8 ) | dmx_buf_back[led*2 + 2])
8

9
        pca9685_led_pwm(PCA9685_CHIP_1, led_map[led], v);
10
   }
11
}
Gast
Hey,


Danke das hilft mir schon mal weiter, werd es heute Abend ausprobieren.


Du hast natürlich recht led*2+1 ist natürlich richtig, wollte da nur 
erstmal alle fehlerquellen ausschließen ?




Lg
Sven
Gast
Nabend,



Soweit so gut, das Funktioniert schon mal danke euch schon mal dafür.


Aber ein Problem habe ich noch.
Ich hätte gerne einen Master Dimmer für diese 4 Kanäle, eigentlich 
Rechnet man 16 Bit * 16 Bit / 16 Bit aber da kommt nur müll bei raus 
evtl hat hier noch jemand einen guten rat.



1
            for(led = 0; led < 4; led++) {
2
        uihelper1 = (dmx_buf_back[led*10 + 1] << 8 ) | dmx_buf_back[led*10 + 2];
3
        uihelper2 = (dmx_buf_back[led*10 + 3] << 8 ) | dmx_buf_back[led*10 + 4];
4
        uihelper3 = (dmx_buf_back[led*10 + 5] << 8 ) | dmx_buf_back[led*10 + 6];
5
        uihelper4 = (dmx_buf_back[led*10 + 7] << 8 ) | dmx_buf_back[led*10 + 8];
6
        dimmer =    (dmx_buf_back[led*10 + 9] << 8 ) | dmx_buf_back[led*10 + 10];
7
          pca9685_led_pwm(PCA9685_CHIP_1, (led*10+0), ((uihelper1 * dimmer)/65535));

LG
Sven
Gast
ShishaLiVe schrieb:
> eigentlich
> Rechnet man 16 Bit * 16 Bit / 16 Bit aber da kommt nur müll bei raus
> evtl hat hier noch jemand einen guten rat.

weil 16bit mal 16bit sehr oft mehr als 16bit sind, da muss man schon mal 
mit 32bit rechnen.
1
pca9685_led_pwm(PCA9685_CHIP_1, (led*10+0), (( (uint32_t)uihelper1 * dimmer)/65535));
Gast
Manchmal hat man einfach ein Brett vorm Kopf, macht natürlich sinn ;-)



Ich bedanke mich für eure Unterstützung.


Und Schönes Wochenende noch ;-)



Lg
Sven
Gast
ShishaLiVe schrieb:
> Leider bin ich nicht der C Profi und hoffe daher auf etwas Unterstützung
> oder Ratschläge.
>
> Hier einmal mein versuch
> while(1) {
>  if(dmx_rx_complete) {
>       uint8_t led = 0;
>       for(led = 0; led < 16; led++) {
>         pca9685_led_pwm(PCA9685_CHIP_1, led_map[led], (dmx_buf_back[led
> + 1] << 8 ) | dmx_buf_back[led + 2]);

Warum muß es denn eigentlich immer maximal unleserlich sein?
Ich formuliere das mal um (ohne deine eher seltsam anmutenden Indices 
wirklich verstanden zu haben):
1
 long L;
2
 int  i;
3
 int  amap;
4

5
if(dmx_rx_complete) 
6
{ i = 0;
7
  while (i<16)
8
  { amap = led_map[i];
9
    L = dmx_buf_back[i+1];
10
    L = (L << 8) | dmx_buf_back[i+2];
11
    pca08154711(PCA_Chip, amap, L);
12
    ++i;
13
  }
14
}
Den Rest, also die ganze Optimiererei, kannst du getrost dem Compiler 
überlassen.

W.S.
Persönliche Seite
W.S. schrieb:
> ShishaLiVe schrieb:
>> Leider bin ich nicht der C Profi und hoffe daher auf etwas Unterstützung
>> oder Ratschläge.
>>
>> Hier einmal mein versuch
>> while(1) {
>>  if(dmx_rx_complete) {
>>       uint8_t led = 0;
>>       for(led = 0; led < 16; led++) {
>>         pca9685_led_pwm(PCA9685_CHIP_1, led_map[led], (dmx_buf_back[led
>> + 1] << 8 ) | dmx_buf_back[led + 2]);
>
> Warum muß es denn eigentlich immer maximal unleserlich sein?

Weil eine for-Schleife besser lesbar ist als das da:

> Ich formuliere das mal um (ohne deine eher seltsam anmutenden Indices
> wirklich verstanden zu haben):
>
> { i = 0;
>   while (i<16)
>   { ...
>     ++i;

Mal abgesehen davon, dass es keiner Coding-Rule folgt :-)

Wenn man das Zusammenbauen von 2 Bytes in einen 16-Bit Wert öfter 
braucht oder leserlicher haben will, dann geht nix über eine 
inline-Funktion.

>  long L;

hä?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.