8 Bit zu 16 Bit Fehler in der Zusammenführung

Gast #4905361
Lesenswert?

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 #4905391
Lesenswert?

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 #4905397
Lesenswert?

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 #4908309
Lesenswert?

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 #4911030
Lesenswert?

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 #4919173
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren