adafruit / Adafruit_WICED_Arduino

Adafruit WICED Feather Arduino BSP
https://www.adafruit.com/products/3056
27 stars 19 forks source link

USBSerial Does not read correctly - 0xFF read as 0x00 #41

Closed NickWaterton closed 8 years ago

NickWaterton commented 8 years ago

when trying to use Serial.read() to read from the USB port, all byte values of 0xFF are read as 0x00.

This makes trying to read anything other than plain text (eg binary data) impossible.

I have tested this behavior with a simple sketch and python script:

Sketch:

#include "Adafruit_FeatherOLED_WiFi.h"
#include <adafruit_feather.h>

//OLED Featherwing display
#define OLED_RESET 4
Adafruit_FeatherOLED_WiFi display(OLED_RESET);

void setup() {
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.init();  // initialize with the I2C addr 0x3C (for the 128x32)
  display.clearDisplay();
  display.setRotation(2); //get display the right way up
  display.setTextWrap(false); //don't wrap text
  display.setTextColor(WHITE,BLACK);

  display.setCursor(0,0);
  display.print("Waiting for Serial");
  display.display();

  Serial.begin(115200); // Initialize Serial USB (doesn't actually do anything)
  while(!Serial); //wait for serial port
  display.clearDisplay();
}

void loop() {
  // loopback bytes receved on serial

  if(Serial.available()) {
    uint8_t c = Serial.read();
    display.clearDisplay();
    display.setCursor(0,0);
    display.print("read: 0x");display.println(c, HEX);
    display.print("read: 0d");display.println(c, DEC);
    display.display();
    Serial.write(c);
  }
}

Python Script:

#!/usr/bin/env python

'''
Test for serial send/receive
'''
import time
import serial

port = "COM13"

ser = serial.Serial(port)     #loopback

try:
    while not ser.isOpen():
        time.sleep(1)

    print "Coms port %s is now open" % port

    for i in range(0,256):
        print "sent: %d" % i
        ser.write(chr(i))
        time.sleep(0.25)

    readback=ser.read(ser.in_waiting)
    print "received %d bytes " % len(readback)
    print (":".join("{:02x}".format(ord(c)) for c in readback))

    print "End of Data"

except Exception as e:
    print 'exception', e

finally:
    ser.close()
    print "serial ports closed"

Output is:

Coms port COM13 is now open
sent: 0
sent: 1
sent: 2
sent: 3
sent: 4
sent: 5
sent: 6
sent: 7
sent: 8
sent: 9
sent: 10
sent: 11
sent: 12
sent: 13
sent: 14
sent: 15
sent: 16
sent: 17
sent: 18
sent: 19
sent: 20
sent: 21
sent: 22
sent: 23
sent: 24
sent: 25
sent: 26
sent: 27
sent: 28
sent: 29
sent: 30
sent: 31
sent: 32
sent: 33
sent: 34
sent: 35
sent: 36
sent: 37
sent: 38
sent: 39
sent: 40
sent: 41
sent: 42
sent: 43
sent: 44
sent: 45
sent: 46
sent: 47
sent: 48
sent: 49
sent: 50
sent: 51
sent: 52
sent: 53
sent: 54
sent: 55
sent: 56
sent: 57
sent: 58
sent: 59
sent: 60
sent: 61
sent: 62
sent: 63
sent: 64
sent: 65
sent: 66
sent: 67
sent: 68
sent: 69
sent: 70
sent: 71
sent: 72
sent: 73
sent: 74
sent: 75
sent: 76
sent: 77
sent: 78
sent: 79
sent: 80
sent: 81
sent: 82
sent: 83
sent: 84
sent: 85
sent: 86
sent: 87
sent: 88
sent: 89
sent: 90
sent: 91
sent: 92
sent: 93
sent: 94
sent: 95
sent: 96
sent: 97
sent: 98
sent: 99
sent: 100
sent: 101
sent: 102
sent: 103
sent: 104
sent: 105
sent: 106
sent: 107
sent: 108
sent: 109
sent: 110
sent: 111
sent: 112
sent: 113
sent: 114
sent: 115
sent: 116
sent: 117
sent: 118
sent: 119
sent: 120
sent: 121
sent: 122
sent: 123
sent: 124
sent: 125
sent: 126
sent: 127
sent: 128
sent: 129
sent: 130
sent: 131
sent: 132
sent: 133
sent: 134
sent: 135
sent: 136
sent: 137
sent: 138
sent: 139
sent: 140
sent: 141
sent: 142
sent: 143
sent: 144
sent: 145
sent: 146
sent: 147
sent: 148
sent: 149
sent: 150
sent: 151
sent: 152
sent: 153
sent: 154
sent: 155
sent: 156
sent: 157
sent: 158
sent: 159
sent: 160
sent: 161
sent: 162
sent: 163
sent: 164
sent: 165
sent: 166
sent: 167
sent: 168
sent: 169
sent: 170
sent: 171
sent: 172
sent: 173
sent: 174
sent: 175
sent: 176
sent: 177
sent: 178
sent: 179
sent: 180
sent: 181
sent: 182
sent: 183
sent: 184
sent: 185
sent: 186
sent: 187
sent: 188
sent: 189
sent: 190
sent: 191
sent: 192
sent: 193
sent: 194
sent: 195
sent: 196
sent: 197
sent: 198
sent: 199
sent: 200
sent: 201
sent: 202
sent: 203
sent: 204
sent: 205
sent: 206
sent: 207
sent: 208
sent: 209
sent: 210
sent: 211
sent: 212
sent: 213
sent: 214
sent: 215
sent: 216
sent: 217
sent: 218
sent: 219
sent: 220
sent: 221
sent: 222
sent: 223
sent: 224
sent: 225
sent: 226
sent: 227
sent: 228
sent: 229
sent: 230
sent: 231
sent: 232
sent: 233
sent: 234
sent: 235
sent: 236
sent: 237
sent: 238
sent: 239
sent: 240
sent: 241
sent: 242
sent: 243
sent: 244
sent: 245
sent: 246
sent: 247
sent: 248
sent: 249
sent: 250
sent: 251
sent: 252
sent: 253
sent: 254
sent: 255
received 256 bytes
00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27:28:29:2a:2b:2c:2d:2e:2f:30:31:32:33:34:3
5:36:37:38:39:3a:3b:3c:3d:3e:3f:40:41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54:55:56:57:58:59:5a:5b:5c:5d:5e:5f:60:61:62:63:64:65:66:67:68:69:6a
:6b:6c:6d:6e:6f:70:71:72:73:74:75:76:77:78:79:7a:7b:7c:7d:7e:7f:80:81:82:83:84:85:86:87:88:89:8a:8b:8c:8d:8e:8f:90:91:92:93:94:95:96:97:98:99:9a:9b:9c:9d:9e:9f:
a0:a1:a2:a3:a4:a5:a6:a7:a8:a9:aa:ab:ac:ad:ae:af:b0:b1:b2:b3:b4:b5:b6:b7:b8:b9:ba:bb:bc:bd:be:bf:c0:c1:c2:c3:c4:c5:c6:c7:c8:c9:ca:cb:cc:cd:ce:cf:d0:d1:d2:d3:d4:d
5:d6:d7:d8:d9:da:db:dc:dd:de:df:e0:e1:e2:e3:e4:e5:e6:e7:e8:e9:ea:eb:ec:ed:ee:ef:f0:f1:f2:f3:f4:f5:f6:f7:f8:f9:fa:fb:fc:fd:fe:00
End of Data
serial ports closed

Notice that the last 255 sent is read as 00. This is confirmed as a USBSerial.read error by the onboard OLED display.

I am willing to try experimental libraries, or fixes as this is a deal breaker for my project right now. The protocol I am using sends the data size in the header, and with FF being read as 00 this will not work (quite apart from trying to avoid ff in binary data is not a possibility).

Help would be appreciated!

NickWaterton commented 8 years ago

I do seem to have come up with a workaround, it seems that Serial.peek() returns the correct value!

So if I perform a Serial.peek(), then a Serial.read() and throw away the Serial.read(), I can get the correct values from USBSerial.

here's the Sketch to prove it:

#include "Adafruit_FeatherOLED_WiFi.h"
#include <adafruit_feather.h>

//OLED Featherwing display
#define OLED_RESET 4
Adafruit_FeatherOLED_WiFi display(OLED_RESET);

void setup() {
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.init();  // initialize with the I2C addr 0x3C (for the 128x32)
  display.clearDisplay();
  display.setRotation(2); //get display the right way up
  display.setTextWrap(false); //don't wrap text
  display.setTextColor(WHITE,BLACK);

  display.setCursor(0,0);
  display.print("Waiting for Serial");
  display.display();

  Serial.begin(115200); // Initialize Serial USB (doesn't actually do anything)
  while(!Serial); //wait for serial port
  display.clearDisplay();
}

void loop() {
  // loopback bytes receved on serial

  if(Serial.available()) {
    display.clearDisplay();
    display.setCursor(0,0);
    uint8_t p = Serial.peek();
    display.print("peek: 0x");display.println(p, HEX);
    display.print("peek: 0d");display.println(p, DEC);
    uint8_t c = Serial.read();
    display.print("read: 0x");display.println(c, HEX);
    display.print("read: 0d");display.println(c, DEC);
    display.display();
    Serial.write(p);
  }
}

output:

sent: 253
sent: 254
sent: 255
received 256 bytes
00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27:28:29:2a:2b:2c:2d:2e:2f:30:31:32:33:34:3
5:36:37:38:39:3a:3b:3c:3d:3e:3f:40:41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54:55:56:57:58:59:5a:5b:5c:5d:5e:5f:60:61:62:63:64:65:66:67:68:69:6a
:6b:6c:6d:6e:6f:70:71:72:73:74:75:76:77:78:79:7a:7b:7c:7d:7e:7f:80:81:82:83:84:85:86:87:88:89:8a:8b:8c:8d:8e:8f:90:91:92:93:94:95:96:97:98:99:9a:9b:9c:9d:9e:9f:
a0:a1:a2:a3:a4:a5:a6:a7:a8:a9:aa:ab:ac:ad:ae:af:b0:b1:b2:b3:b4:b5:b6:b7:b8:b9:ba:bb:bc:bd:be:bf:c0:c1:c2:c3:c4:c5:c6:c7:c8:c9:ca:cb:cc:cd:ce:cf:d0:d1:d2:d3:d4:d
5:d6:d7:d8:d9:da:db:dc:dd:de:df:e0:e1:e2:e3:e4:e5:e6:e7:e8:e9:ea:eb:ec:ed:ee:ef:f0:f1:f2:f3:f4:f5:f6:f7:f8:f9:fa:fb:fc:fd:fe:ff
End of Data
serial ports closed
hathach commented 8 years ago
Serial.begin(115200); // Initialize Serial USB (doesn't actually do anything)
while(!Serial); //wait for serial port

First of all, it is not relevant but you should not simply while (!Serial); since it will not release the CPU control to process other tasks in featherlib, which handle USBSerial connection event. Please change it to

while(!Serial) delay(1); //wait for serial port

hathach commented 8 years ago

It seems like 0xFF (-1) is misunderstanding as EOF for no data available.

hathach commented 8 years ago

This issue should be fixed with the development branch's featherlib.bin (featherlib version 0.5.5).

  1. Switch repo code to development branch
  2. Change section to "featherlib (release)"
  3. click upload
  4. Change section back to "User code"
  5. Re run your test's sketch.

Please confirm if it works for you with the Serial.read(), we will close this then.

NickWaterton commented 8 years ago

Thanks for the info about putting delay(1) in the loop.

I have tested as you suggested, and can confirm that the problem is resolved.

Thanks.