Bluetooth incoming data string distortion - vba

I have scales equipped with RS232 serial port and a Bluetooth transmitter. I made a program in VBA to receive data from the scales. However, lets say out of 10 incoming strings I get 3 distorted. My regular strings look like: "+001500./3 G S". This means 1500.3 grams above zero and the output is stable. But sometimes I get strings like separated like "+" or "001500./3" or "G S". When I plug serial cable I have no distortions.

Serial ports are just byte streams. You can never make assumptions about how many of the bytes will show up on each read operation. It's only coincidence that when you use a real cable you read the whole string at once. You have to do the string splitting yourself, and continue reading when you only get a partial result.

Related

Accessing a combination of ports by adding both their offsets to a base address. How would this work?

Context: I am following an embedded systems course https://www.edx.org/course/embedded-systems-shape-the-world-microcontroller-i
In the lecture on bit specific addressing they present the following example on a "peanut butter and jelly port".
Given you a port PB which has a base address of 0x40005000 and you wanted to access both port 4 and port 6 from PB which would be PB6 and PB4 respectively. One could add the offset of port 4(0x40) and port 6(0x100) to the base address(0x40005000) and define that as their new address 0x40005140.
Here is where I am confused. If I wanted to define the address for PB6 it would be base(0x40005000) + offset(0x100) = 0x40005100 and the address for PB4 would be base(0x40005000) + offset(0x40) = 0x40005040. So how is it that to access both of them I could use base(0x40005000) + offset(0x40) + offset(0x100) = 0x40005140? Is this is not an entirely different location in memory for them individually?
Also why is bit 0 represented as 0x004. In binary that would be 0000 0100. I suppose it would represent bit 0 if you disregard the first two binary bits but why are we disregarding them?
Lecture notes on bit specific addressing:
Your interpretation of how memory-mapped registers are addressed is quite reasonable for any normal peripheral on an ARM based microcontroller.
However, if you read the GPIODATA register definition on page 662 of the TM4C123GH6PM datasheet then you will see that this "register" behaves very differently.
They map a huge block of the address space (1024 bytes) to a single 32-bit register. This means that bits[9:2] of the the address bus are not needed, and are in fact overloaded with data. They contain the mask of the bits to be updated. This is what the "offset" calculation you have copied is trying to describe.
Personally I think this hardware interface could be a very clever way to let you set only some of the outputs within a bank using a single atomic write, but it makes this a very bad choice of device to use for teaching, because this isn't the way things normally work.

Is there a method for arudino to store values into different variables as soon as they come over a serial connection?

I have built an android app that will send a string of values (using getbyte()_) across a serial connection. I would like each of these values to be stored in a seperate variable/
For example:
a list of numbers like this:
10004056700003
are sent across the connection.
there are a bunch of variables on the arduino side:
A,B,C,D.... etc
i would like to be able to do this:
A = 1
B = 0
C = 0
D = 0
E = 4
F= 0
.... and so on. i will then use these variables to run a certain sequence of functions on the arduino. In this sense the android application is just to control the arduino.
Thanks for the help! :D
Serial communication usually happens byte-wise.
So if you want to transfer a sequence of numbers (>255) the easiest way is to send each digit as a byte.
On the receiving end you basically have two options.
a) you read each byte and do something with it befor reading the next byte.
b) you read the bytes into a buffer array and do something with it later.
If you want to minimize the number of bytes transferred you of course can split the number value into several bytes instead of transferring each digit.
Try sending the data as String, and then you can access each character of the String using the method: StringVariableName.charAt(pos);
With this approach, your code will be more readable.
Check out charAt function here.

Gps nmea output getting valid $GPGSV but not valid $GPGGA $GPRMC

I'm trying to parse gps nmea output from a modem connected to serial port of a cubietruck board (ARM® Cortex™-A7 Dual-Core). The configuration is done succesfully I get 4g network form modem but when I try to see nmea outout of the gps module, I get the following :
$GPRMC,,V,,,,,,,,,,N*53
$GPGSV,2,1,08,07,49.9,43.6,28.2,28,49.9,158.9,29.2,02,3.5,239.1,,05,49.9,286.9,E
$GPGSV,2,2,08,06,,,,08,9.8,68.9,,09,31.6,104.1,,13,20.4,299.5,,1*5E
$GNGNS,112218.9,,,,,NNN,,,,,,*03
$GPVTG,,T,,M,,N,,K,N*2C
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GNGSA,A,1,,,,,,,,,,,,,,,*00
$GPGGA,,,,,,0,,,,,,,,*66
$GPRMC,,V,,,,,,,,,,N*53
$GPGSV,2,1,08,07,49.9,43.6,27.9,28,49.9,158.9,29.7,02,3.5,239.1,,05,49.9,286.9,F
$GPGSV,2,2,08,06,,,,08,9.8,68.9,,09,31.6,104.1,,13,20.4,299.5,,1*5E
$GNGNS,112219.9,,,,,NNN,,,,,,*02
Looking in http://aprs.gids.nl/nmea/ I found that $GPGSV is GPS Satellites in view. So what I understand is that I get 2 satellites. Is this perhaps the case that I don't get valid $GPGGA $GPRMC or should I check something else?
You don't have a positional "fix" and therefore get empty values in some of the telegrams. As you probably know, there should be latitude, longitude and other data instead of empty values between the commas. Two satellites are not enough to get a fix, you need at least 3 or 4 to get the position.
The NMEA 0183 standard is weakly defined and doesn't mention what GPS units should do when they don't have a positional fix. Sending empty values is pretty common, but some units might act differently. You can easily tell whether the data is valid or not from the A and V letters. V means void and A means active. In the RMC telegram, you can see a V, meaning the entire thing is void.
The reason you get values in the GSV telegrams is because the GPS is able to see two satellites and therefore calculate the values needed in the telegram.
The third field, 08, is the theoretical number of satellites you would be able to see in good conditions.
So what you have to do is to take the GPS outdoors or connect it to a proper antenna. It will start sending proper values when it's able to see the satellites.
Actually by your two GPGSV sentences you can see 08 satellites - eight of them. You have 2 'sentences' of GSV 2,1,08 means 1 of 2 sentences describing 08 satellites, and 2,2,08 means 2 of 2 sentences describing 08 satellites

Erlang binary protocol serialization

I'm currently using Erlang for a big project but i have a question regarding a proper proceeding.
I receive bytes over a tcp socket. The bytes are according to a fixed protocol, the sender is a pyton client. The python client uses class inheritance to create bytes from the objects.
Now i would like to (in Erlang) take the bytes and convert these to their equivelant messages, they all have a common message header.
How can i do this as generic as possible in Erlang?
Kind Regards,
Me
Pattern matching/binary header consumption using Erlang's binary syntax. But you will need to know either exactly what bytes or bits your are expecting to receive, or the field sizes in bytes or bits.
For example, let's say that you are expecting a string of bytes that will either begin with the equivalent of the ASCII strings "PUSH" or "PULL", followed by some other data you will place somewhere. You can create a function head that matches those, and captures the rest to pass on to a function that does "push()" or "pull()" based on the byte header:
operation_type(<<"PUSH", Rest/binary>>) -> push(Rest);
operation_type(<<"PULL", Rest/binary>>) -> pull(Rest).
The bytes after the first four will now be in Rest, leaving you free to interpret whatever subsequent headers or data remain in turn. You could also match on the whole binary:
operation_type(Bin = <<"PUSH", _/binary>>) -> push(Bin);
operation_type(Bin = <<"PULL", _/binary>>) -> pull(Bin).
In this case the "_" variable works like it always does -- you're just checking for the lead, essentially peeking the buffer and passing the whole thing on based on the initial contents.
You could also skip around in it. Say you knew you were going to receive a binary with 4 bytes of fluff at the front, 6 bytes of type data, and then the rest you want to pass on:
filter_thingy(<<_:4/binary, Type:6/binary, Rest/binary>>) ->
% Do stuff with Rest based on Type...
It becomes very natural to split binaries in function headers (whether the data equates to character strings or not), letting the "Rest" fall through to appropriate functions as you go along. If you are receiving Python pickle data or something similar, you would want to write the parsing routine in a recursive way, so that the conclusion of each data type returns you to the top to determine the next type, with an accumulated tree that represents the data read so far.
I only covered 8-bit bytes above, but there is also a pure bitstring syntax, which lets you go as far into the weeds with bits and bytes as you need with the same ease of syntax. Matching is a real lifesaver here.
Hopefully this informed more than confused. Binary syntax in Erlang makes this the most pleasant binary parsing environment in a general programming language I've yet encountered.
http://www.erlang.org/doc/programming_examples/bit_syntax.html

Is this GPGSV sentence valid?

While parsing the NMEA output of a GPS receiver I get the following lines:
$GPGSV,4,1,16,02,17,228,35,03,04,048,37,05,59,285,29,06,02,030,34*73
$GPGSV,4,2,16,07,58,061,46,08,80,159,40,09,11,227,32,10,51,167,47*77
$GPGSV,4,3,16,13,15,089,38,15,00,279,,16,00,018,,26,34,279,42*7A
$GPGSV,4,4,16,28,20,154,39*4C
As I understand it, from various sources on the web (e.g. here), this is wrong. According to the 3rd number, there should be 16 satellites, which was true for all those GPS receivers I previously encountered, but the sentence from this one only contains the data for 13 satellites.
Is this an error? Or do I read the specification wrongly?
Nmea is a weakly specified file format. GPS chip manufactures provide documenttaion how they interpret the NMEA specification.
For example ublox and Sirf each have a chapter of about 40 pages describing how to interpret the NMEA format.
So if you write " Or do I read the specification wrongly?", then the question is which specification you are reading. That of the GPS chip manufacturer? The NMEA 0183 spec does not contain enough info to correctly parse the sentences.
Especially in your case: the NMEA protocol does not desribe how to handle empty values vs invalid ones.
In your case the receiver theretically expects to see 16 satellites, but found only 13.
I would expect that the missing 3 sats would have empty ",,,,,,,,". But obviously the manufacturer decided to just stop and append the checksum string. (Its simply not speciefied that it is mandatory to print out empty semicolons for the missing 3 sats.
Unfortunaetly you have to expect to write a NMEA parser for each CHPS chip manufacturer.
Therfore I always recommend to use the binary format of the Chip manufactureres protocol. (e,.g uBlox bianry or Sirf binary because these are exactly specified).
You can further look at the docu for GpsBable: they show how different manufacturres produce different GSV data sets.
Update:
As you now told that it is a ublox receiver:
The answer is, yes the NMEA sentences are valid. Look at the ublox protocol spec. i use spec for ublox 5:
On page where the GSV sentence is described look at the "Message Structure":
{,sv,elv,az,cno}*cs
the curly braces enclose the sequence that is repeated.
And below look at "1..4": this means 1,2,3 or 4 blocks. There is not written "4", its "1..4" therefore satelite info is optional, and has not to be empty.
If you further look at the example ublox gives, then you see, that the last GPGSV message contains less than 4 satellites, exactly as you are showing in your question.
Yes, it's inconsistent; the last message should have described more than one satellite (four, actually) so as to total the 16 advertised. The GPS receiver should have reported at least the satellite IDs (PRN), even if their viewing direction in the sky and SNR were unknown at the time, e.g.: {,01,,,}.
That being said, it's better to write programs tolerant against ill-formed messages; in this case, updating the number of satellites in view to 13, as counted.
(I've checked the checksums and they're okay.)