Arduino Bit Shifting Problem

OP #6011130
Lesenswert?

Hallo liebe Freunde habe kein kleines Problem möchte gerne einen String 
den ich ausgelesen habe folgendermaßen verändern

1
Quell String 80482780C1
2
80    48    27    80    C1
3
10000000  10010000  00100111  10000000  11000001
4

5

6
Ziel String 0112E40183
7
01    12    E4    01    83
8
00000001  00010010  11100100  00000001  10000011

Der String wurder Seriell ausgelesen nun stehe ich da und weiss nicht 
weiter !
OP #6011213
Lesenswert?

das frage ich mich auch gerade da sie nicht in der Referenz erwähnt 
wird.


hier mal mein ganzer code
1
#include <Arduino.h> 
2
#include <hd44780.h>
3
#include <hd44780ioClass/hd44780_pinIO.h>
4

5

6
//Display PinSetup
7
//const int rs = 12, en = 11, db4 = 10, db5 = 9, db6 = 8, db7 = 7;
8
//Piazo Pin Setup
9
const int buzzer = 2;
10
int PowerOn = 0;
11
hd44780_pinIO lcd(12, 11, 10, 9, 8, 7);
12
const int LCDCols = 20;
13
const int LCDRow = 4;
14

15
#define LCD_COLS 20
16
#define LCD_ROWS 4
17
#define HD44780_LCDOBJECT
18

19

20

21
String HITAG1 = "h";
22
String HITAG2 = "H";
23
String EM4102 = "U";
24
String EM4150 = "T";
25

26

27
String ver;
28
String id;
29
String lastscan;
30
String idshort;
31
String MTid;
32

33
void setup()   { 
34
                    pinMode(buzzer, OUTPUT);
35
                    Serial1.begin(9600);
36
                    Serial1.setTimeout(50);
37
                    lcd.begin(20, 4);
38
                }
39
                                
40

41

42

43

44

45
void loop() 
46
                        {   
47
                            if ( ( (PowerOn) == 1 ) && ( (ver.length()) >= 4 ) )
48
                                {
49
                                    Scannen();
50
                                }
51
                            else VersionCheck();
52

53

54
                        }
55

56
//Ruft die Version des Kekses ab und Speichert ihn als String ver
57
String VersionCheck ()      {   Serial.println("Version");
58
                                digitalWrite(buzzer, HIGH);
59
                                delay(800);
60
                                digitalWrite(buzzer, LOW);
61
                                lcd.print ("Scanner 01");
62
                                lcd.setCursor(0,1);
63
                                Serial1.write("v");
64
                                while (!Serial1.available())
65
                                {
66
                                }
67
                                ver = Serial1.readString();                      
68
                                ver.trim();
69
                                lcd.print(String(ver));
70
                                delay(1500);
71
                                PowerOn=1;
72
                                return (ver);
73
                            }
74

75

76

77
//Scannt die ID und übergibt den String
78
String Scannen()
79
                        {
80
                                        Serial1.write("rid");
81
  
82
                                        while (!Serial1.available())
83
                                        {
84
                                        Serial.println("while");
85

86
                                        }
87

88
                                        id = Serial1.readString();                      
89
                                        id.trim();
90
                                        Serial.println(id);
91
                                        
92
                                        Serial1.flush();
93

94
                                        if ((id.length()) > 4 && id != lastscan )
95
                                                
96
                                                {
97
                                                    lcd.setCursor(0,1);
98
                                                    lcd.print("                  ");
99
                                                    lcd.setCursor(0,1);
100
                                                    digitalWrite(buzzer, HIGH);
101
                                                    delay(50);
102
                                                    digitalWrite(buzzer, LOW);
103
                                                    lcd.print("ID:" + id);
104
                                                    lcd.setCursor(0,1);
105
                                                    Serial.println("SCAN1");
106
                                                    idshort = id;
107
                                                    idshort.remove(0,1);
108

109

110

111

112

113

114

115

116
                                                    
117
                                                    if ( id.startsWith(HITAG1) )
118

119
                                                                {
120
                                                                    lcd.setCursor(0,3);
121
                                                                    lcd.print("Typ: HITAG 1");
122
                                                                    lcd.setCursor(0,1);
123
                                                                }
124
                                                    
125
                                                    else if ( id.startsWith(HITAG2) )
126

127
                                                                {
128
                                                                    lcd.setCursor(0,3);
129
                                                                    lcd.print("Typ: HITAG 2");
130
                                                                    lcd.setCursor(0,1);
131
                                                                }
132

133
                                                    else if ( id.startsWith(EM4102) )
134

135
                                                                {   
136
                                                                    lcd.setCursor(0,2);
137
                                                                    lcd.print("MTID:" + byte0i);
138
                                                                    lcd.setCursor(0,3);
139
                                                                    lcd.print("Typ: EM4102");
140
                                                                    lcd.setCursor(0,1);
141
                                                                }
142
                                                    else if ( id.startsWith(EM4150) )
143

144
                                                                {
145
                                                                    lcd.setCursor(0,3);
146
                                                                    lcd.print("Typ: EM4150");
147
                                                                    lcd.setCursor(0,1);
148
                                                                }
149
                                                    
150
                                                    else        {
151
                                                                    lcd.setCursor(0,3);
152
                                                                    lcd.print("Typ: UNBEKANNT");
153
                                                                    lcd.setCursor(0,1);
154
                                                                }
155

156
                                                }
157

158

159

160
                                        else if ( ((id.length()) <= 4 ) && id != lastscan)
161
                                                {
162
                                                            lcd.setCursor(0,1);
163
                                                            lcd.print("KEIN TAG ERKANNT!");
164
                                                            lcd.setCursor(0,3);
165
                                                            lcd.print("                    ");
166
                                                            lcd.setCursor(0,1);
167
                                                }
168

169
                                        
170

171
                                        lastscan = id;
172
                                        
173
                                        return id;
174
                                
175
                        }
#6011302
Lesenswert?

Selbst für einen Arduino-Programmierer sollte es möglich sein, eine so 
banale Funktion schnell selber zu schreiben:
1
uint8_t MirrorByte ( uint8_t ToMirrorByte ){
2
 uint8_t MirroredByte = 0;
3
 for (uint8_t BitNr = 0; BitNr < 8; BitNr++){
4
    if ( ToMirrorByte & (1<<BitNr)) MirroredByte |= (1<<(7-BitNr));
5
 }
6
 return MirroredByte;
7
}

Quick&Dirty
Gast #6011326
Lesenswert?

Hi

>Hatte mich schon gewundert das du C programmierst, du bist doch ASM
>Spezi nicht wahr?

Na ja. Manchmal kommt auch C-Spezies etwas brauchbares. Eine 
ASM-Umsetzung dieses Codes habe ich in meiner Mathe Lib.

MfG Spess
Gast #6011385
Lesenswert?

Hi

>In ASM ist das Problem ja so trivial lösbar...
>8mal ROL und ROR in einer Schleife geht rasend schnell.

Also mindestens 24 Befehle + Kleinkram.

Da ist PeDas Routine kürzer und schneller

[avrasm]
mirror_fast:          push r17
                      swap r16
                      mov r17,r16

                      lsr r16
                      lsr r16
                      lsl r17
                      lsl r17
                      andi r16,$33
                      andi r17,$CC

                      or r16,r17
                      mov r17,r16

                      lsr r16
                      lsl r17
                      andi r16,$55
                      andi r17,$AA
                      or r16,r17
                      pop r17
                      ret

[{avrasm]


MfG Spess
Gast #6011405
Lesenswert?

Man betrachte den Titel:  Arduino Bit Shifting Problem

- Es stellt sich heraus dass das Anliegen nichts mit
Bit shiften zu tun hat.

- es darf gefragt werden was denn Arduino mit Bit
Shifting zu tun hat (klingt nach: "der Arduino kann
nicht Bit shiften").

- der TO ist nicht fähig die Hinweise zum Posten von
Quelltext zu lesen und umzusetzen.

Da geht es in einem Thread drunter und drüber, was für
eine verquere Welt .....
Gast #6011419
Lesenswert?

Hi

Über den Dingen (Gast) schrieb

>- Es stellt sich heraus dass das Anliegen nichts mit
>  Bit shiften zu tun hat.

Wieso nicht? In allen vorgestellten Lösungen wird 'geshiftet'.

Der Rest von dir ist genauso daneben.

MfG Spess
#6011526
Lesenswert?

OK: AVR-GCC9.2.0, Optimierung = Os
1
uint8_t MirrorByte ( const uint8_t ToMirrorByte ){
2
  52:  cf 93         push  r28
3
  54:  df 93         push  r29
4
  56:  30 e0         ldi  r19, 0x00  ; 0
5
  58:  20 e0         ldi  r18, 0x00  ; 0
6
  uint8_t MirroredByte = 0;
7
  5a:  90 e0         ldi  r25, 0x00  ; 0
8
  for (uint8_t BitNr = 0; BitNr < 8; BitNr++){
9
    if ( ToMirrorByte & (1<<BitNr)) MirroredByte |= (1<<(7-BitNr));
10
  5c:  48 2f         mov  r20, r24
11
  5e:  50 e0         ldi  r21, 0x00  ; 0
12
  60:  67 e0         ldi  r22, 0x07  ; 7
13
  62:  70 e0         ldi  r23, 0x00  ; 0
14
  64:  e1 e0         ldi  r30, 0x01  ; 1
15
  66:  f0 e0         ldi  r31, 0x00  ; 0
16
  68:  da 01         movw  r26, r20
17
  6a:  02 2e         mov  r0, r18
18
  6c:  02 c0         rjmp  .+4        ; 0x72 <MirrorByte+0x20>
19
  6e:  b5 95         asr  r27
20
  70:  a7 95         ror  r26
21
  72:  0a 94         dec  r0
22
  74:  e2 f7         brpl  .-8        ; 0x6e <MirrorByte+0x1c>
23
  76:  a0 ff         sbrs  r26, 0
24
  78:  0a c0         rjmp  .+20       ; 0x8e <MirrorByte+0x3c>
25
  7a:  db 01         movw  r26, r22
26
  7c:  a2 1b         sub  r26, r18
27
  7e:  b3 0b         sbc  r27, r19
28
  80:  ef 01         movw  r28, r30
29
  82:  02 c0         rjmp  .+4        ; 0x88 <MirrorByte+0x36>
30
  84:  cc 0f         add  r28, r28
31
  86:  dd 1f         adc  r29, r29
32
  88:  aa 95         dec  r26
33
  8a:  e2 f7         brpl  .-8        ; 0x84 <MirrorByte+0x32>
34
  8c:  9c 2b         or  r25, r28
35
  for (uint8_t BitNr = 0; BitNr < 8; BitNr++){
36
  8e:  2f 5f         subi  r18, 0xFF  ; 255
37
  90:  3f 4f         sbci  r19, 0xFF  ; 255
38
  92:  28 30         cpi  r18, 0x08  ; 8
39
  94:  31 05         cpc  r19, r1
40
  96:  41 f7         brne  .-48       ; 0x68 <MirrorByte+0x16>
41
  }
42
  return MirroredByte;
43
}
44
  98:  89 2f         mov  r24, r25
45
  9a:  df 91         pop  r29
46
  9c:  cf 91         pop  r28
47
  9e:  08 95         ret
#6011531
Lesenswert?

AVR-GCC9.2.0, Optimierung = O3
1
uint8_t MirrorByte ( const uint8_t ToMirrorByte ){
2
  uint8_t MirroredByte = 0;
3
  for (uint8_t BitNr = 0; BitNr < 8; BitNr++){
4
  cc:  83 2f         mov  r24, r19
5
  ce:  90 e0         ldi  r25, 0x00  ; 0
6
    if ( ToMirrorByte & (1<<BitNr)) MirroredByte |= (1<<(7-BitNr));
7
  d0:  23 2f         mov  r18, r19
8
  d2:  21 70         andi  r18, 0x01  ; 1
9
  d4:  30 fd         sbrc  r19, 0
10
  d6:  20 e8         ldi  r18, 0x80  ; 128
11
  d8:  81 fd         sbrc  r24, 1
12
  da:  20 64         ori  r18, 0x40  ; 64
13
  dc:  82 fd         sbrc  r24, 2
14
  de:  20 62         ori  r18, 0x20  ; 32
15
  e0:  83 fd         sbrc  r24, 3
16
  e2:  20 61         ori  r18, 0x10  ; 16
17
  e4:  84 fd         sbrc  r24, 4
18
  e6:  28 60         ori  r18, 0x08  ; 8
19
  e8:  85 fd         sbrc  r24, 5
20
  ea:  24 60         ori  r18, 0x04  ; 4
21
  ec:  86 fd         sbrc  r24, 6
22
  ee:  22 60         ori  r18, 0x02  ; 2
23
  f0:  88 0f         add  r24, r24
24
  f2:  89 2f         mov  r24, r25
25
  f4:  88 1f         adc  r24, r24
26
  f6:  99 0b         sbc  r25, r25
27
  f8:  89 2b         or  r24, r25
28
  fa:  09 f0         breq  .+2        ; 0xfe <__stack+0x5f>
29
  fc:  21 60         ori  r18, 0x01  ; 1
30
  Dummy2 = MirrorByte( Dummy1 );
31
  fe:  20 93 65 00   sts  0x0065, r18  ; 0x800065 <Dummy2>
32
}
Moderator Persönliche Seite #6011541
Lesenswert?

Ingo L. schrieb:
> OK: AVR-GCC9.2.0, Optimierung = Os

Auch zu groß. Lesbare und verständliche Alternative zu PeDas Code:
1
uint8_t mirror (uint8_t b)
2
{
3
    uint8_t nb = 0;
4

5
    if (b & 0x01) nb |= 0x80;
6
    if (b & 0x02) nb |= 0x40;
7
    if (b & 0x04) nb |= 0x20;
8
    if (b & 0x08) nb |= 0x10;
9
    if (b & 0x10) nb |= 0x08;
10
    if (b & 0x20) nb |= 0x04;
11
    if (b & 0x40) nb |= 0x02;
12
    if (b & 0x80) nb |= 0x01;
13
    return nb;
14
}

Eigentlich ist das nix anderes als eine ausgerollte Schleife.
Größe der Funktion mit avr-gcc 4.7.2 -Os: 42 Bytes.
Moderator Persönliche Seite #6011552
Lesenswert?

Ingo L. schrieb:
> Frank M. schrieb:
> Eigentlich ist das nix anderes als eine ausgerollte Schleife.
>
> Eben, die eingerollte Schleife dazu schrieb ich bereits weiter oben

Der Witz ist: Die eingerollte braucht mehr Bytes an Code als die 
ausgerollte.
Aus Deiner LSS lese ich: 50 Bytes, aus meiner LSS lese ich: 42 Bytes.

Die Schleife lohnt sich also erst bei größeren Bitbreiten als 8. Aber 
auch da gibt es für 16Bit und 32 Bits Alternativen, zum Beispiel diese 
hier:
1
uint32_t reverse(uint32_t x, int bits)
2
{
3
    x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); // Swap _<>_
4
    x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); // Swap __<>__
5
    x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); // Swap ____<>____
6
    x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); // Swap ...
7
    x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); // Swap ...
8
    return x >> (32 - bits);
9
}

Zu diesem Thema gabs hier auch schon einen ausführlichen Thread - inkl. 
Lösungsvorschläge über Lookup-Tables (für Nibbles), um so schnell wie 
möglich zu sein.

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