0

I am using a SIM7100 module in a project which has a SIM card in it. I can send and receive texts with no problem until I send an AT+USD command to request the current balance on the SIM. If I use minicom to send the command, I get a (correct) response:

AT+CUSD: 0,"O2: Your balance is £10.84"

I'm using 'import serial' at the start of the program. When I send the same message via Python program, and try to read the answer, I get a decode error when the string has got as far as the '£' sign:

'can't decode byte Oxa3 in position 0. Invalid start byte.'

I've tried to decode in 2 ways, using code as follows:

while port.inWaiting()>0:
response+=str(port.read(1).decode())

and also:

while port.inWaiting()>0:
response+=str(port.read(1).decode(utf-8))

Neither method works and the error is the same. I don't know how to find what encoding method is used by the SIM7100 and I don't know any other options to try. Can anyone help please?

3 Answers3

1

The stream is encoded as latin-1, so decode from latin-1 like this:

port.read(1).decode('latin-1')

Edit:

'£' encoded as latin-1 (and some other 8-bit encodings such as cp1252) is b'\xa3', whereas as 'uf-8' it is b'\xc2\xa3'. If the stream is encoded as UTF-8 then building a response by reading one byte at a time and decoding will not work if the stream contains a character that is encoded as more than one byte. In this case the best approach would be to collect all the bytes before decoding:

response = b''
while port.inWaiting()>0:
    response += port.read(1)
response = response.decode('utf-8')
snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
0

This question and answer should be similar enough to your case:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xa3 in position 3: invalid start byte

As suggested there, to print characters such as 0xa3, either convert them to white spaces or decrypt them.

Inon Peled
  • 691
  • 4
  • 11
  • I don't know how to convert or decrypt them yet. I'll go digging for answers . – David Wigg Mar 19 '19 at 10:27
  • If the £ character is 2 bytes, do I have to read the serial port in 2 char steps so I get the whole thing in one go? I'm lost as to next steps now. – David Wigg Mar 19 '19 at 18:04
0

I added some code to print whatever was received one character at a time and got a complete string including the problem '£'. After some head scratching, I realised that the response to the AT+CUSD command comes in 2 parts, the first is just 'OK', then, a couple of seconds later, the full response: AT+CUSD=1, etc... The decoding resulted in 'Your balance is £20.74' printing as:

Your balance is 2 59 0.74

I realised this was a decoding issue and used latin-1 decoding. I then added a 4 second delay in reading from the buffer if the command was 'AT+CUSD' and Hey Presto! Problem solved. Thanks to all those who provided clues and helpful suggestions/information.