Dette er en modul laget av dfrobot som kan returnere akselerasjon, rotasjonshastighet og vinkel i tre dimensjoner. Her en forklaring av input dataene.
Kommunikasjonsprotokoll: UART
Default baud: 9600
Antall bytes: 44
Data bits: 8
Paritet: Ingen
Stopp bits: 1
Bit rekkefølge: LSB
Spenning: 3V/5V
Måling
Dette er hentet ut fra ocilloscopet.
Packet | Start Time (s) | End Time (s) | Data | Max Voltage (V) | Min Voltage (V) | Voltage Pk-Pk (V) | Packet Time (s) |
---|---|---|---|---|---|---|---|
1 | 0.0516 | 0.0527 | 55 | 3.318 | -0.675 | 3.993 | 0.001042 |
2 | 0.0527 | 0.0537 | 51 | 3.318 | -0.056 | 3.374 | 0.001042 |
3 | 0.0537 | 0.0547 | FD | 3.487 | -0.112 | 3.599 | 0.001042 |
4 | 0.0547 | 0.0558 | FF | 3.318 | -0.112 | 3.431 | 0.001042 |
5 | 0.0558 | 0.0568 | F7 | 3.487 | -0.450 | 3.937 | 0.001042 |
6 | 0.0568 | 0.0579 | FF | 3.431 | -1.575 | 5.005 | 0.001042 |
7 | 0.0579 | 0.0589 | 0F | 3.318 | -1.575 | 4.893 | 0.001042 |
8 | 0.0589 | 0.0599 | 08 | 3.487 | -0.225 | 3.712 | 0.001042 |
9 | 0.0599 | 0.0610 | F3 | 3.374 | -0.169 | 3.543 | 0.001042 |
10 | 0.0610 | 0.0620 | 09 | 3.262 | -1.575 | 4.837 | 0.001042 |
11 | 0.0620 | 0.0630 | AB | 3.262 | -0.619 | 3.881 | 0.001042 |
12 | 0.0630 | 0.0641 | 55 | 3.431 | -1.462 | 4.893 | 0.001042 |
13 | 0.0641 | 0.0651 | 52 | 4.556 | 0.000 | 4.556 | 0.001042 |
14 | 0.0651 | 0.0662 | 02 | 3.318 | -0.056 | 3.374 | 0.001042 |
15 | 0.0662 | 0.0672 | 00 | 3.262 | -0.112 | 3.374 | 0.001042 |
16 | 0.0672 | 0.0682 | 00 | 3.318 | -0.112 | 3.431 | 0.001042 |
17 | 0.0682 | 0.0693 | 00 | 3.431 | -0.225 | 3.656 | 0.001042 |
18 | 0.0693 | 0.0703 | 00 | 4.274 | -0.281 | 4.556 | 0.001042 |
19 | 0.0703 | 0.0714 | 00 | 3.318 | -0.225 | 3.543 | 0.001042 |
20 | 0.0713 | 0.0724 | F3 | 3.318 | -0.225 | 3.543 | 0.001042 |
21 | 0.0724 | 0.0734 | 09 | 3.262 | -0.225 | 3.487 | 0.001042 |
22 | 0.0734 | 0.0745 | A5 | 3.431 | 0.000 | 3.431 | 0.001042 |
23 | 0.0745 | 0.0755 | 55 | 3.824 | -0.056 | 3.881 | 0.001042 |
24 | 0.0755 | 0.0765 | 53 | 3.824 | -0.731 | 4.556 | 0.001042 |
25 | 0.0765 | 0.0776 | CE | 3.431 | -0.169 | 3.599 | 0.001042 |
26 | 0.0776 | 0.0786 | FF | 3.431 | -0.169 | 3.599 | 0.001042 |
27 | 0.0786 | 0.0797 | 0D | 3.374 | -1.012 | 4.387 | 0.001042 |
28 | 0.0797 | 0.0807 | 00 | 3.262 | -0.169 | 3.431 | 0.001042 |
29 | 0.0807 | 0.0817 | D7 | 3.712 | -0.619 | 4.330 | 0.001042 |
30 | 0.0817 | 0.0828 | F8 | 3.262 | 0.000 | 3.262 | 0.001042 |
31 | 0.0828 | 0.0838 | 68 | 3.262 | 0.000 | 3.262 | 0.001042 |
32 | 0.0838 | 0.0848 | 46 | 3.318 | -0.619 | 3.937 | 0.001042 |
33 | 0.0848 | 0.0859 | FF | 3.318 | 0.000 | 3.318 | 0.001042 |
34 | 0.0859 | 0.0869 | 55 | -0.056 | 0.001042 | ||
35 | 0.0869 | 0.0880 | 54 | 3.318 | -1.912 | 5.230 | 0.001042 |
36 | 0.0880 | 0.0890 | 00 | 3.318 | -0.675 | 3.993 | 0.001042 |
37 | 0.0890 | 0.0900 | 00 | 3.318 | -0.225 | 3.543 | 0.001042 |
38 | 0.0900 | 0.0911 | 00 | 3.262 | -0.112 | 3.374 | 0.001042 |
39 | 0.0911 | 0.0921 | 00 | 3.318 | -0.056 | 3.374 | 0.001042 |
40 | 0.0921 | 0.0932 | 00 | 3.262 | 0.000 | 3.262 | 0.001042 |
41 | 0.0931 | 0.0942 | 00 | 3.262 | 0.000 | 3.262 | 0.001042 |
42 | 0.0942 | 0.0952 | 00 | 3.262 | -0.169 | 3.431 | 0.001042 |
43 | 0.0952 | 0.0963 | 00 | 3.318 | -0.169 | 3.487 | 0.001042 |
44 | 0.0963 | 0.0973 | A9 | 3.431 | -0.169 | 3.599 | 0.001042 |
Pakker
Totalt kommer det 4 pakker fra sensoren.
Pakke 1: Aksellerasjonsdata
Pakke 2: Rotasjonshastighet
Pakke 3: Retning
Den fjerde pakken er ikke i bruk, men leverer data.
Felles
Alle pakker starter med byte 0x55. Dette forteller at data pakkedata kommer.
Deretter kommer en pakke som forteller hva pakken inneholder. Hvis byte verdien er 0x51 så kommer det akselerasjonsdata, hvis den er 0x52 så er det rotasjonshastighet og 0x53 så er det retning.
Alle pakker er 11 bytes, nedenfor beskrives pakkene.
Akselerasjon
Blokker
Data | Innhold | Beskrivelse |
---|---|---|
0 | 0x55 | Pakke header |
1 | 0x51 | Akselerasjonspakke |
2 | AXL | X akse akselerasjon 8 laveste bits |
3 | AXH | X akse akselerasjon 8 høyeste bits |
4 | AYL | Y akse akselerasjon 8 laveste bits |
5 | AYH | Y akse akselerasjon 8 høyeste bits |
6 | AZL | Z akse akselerasjon 8 laveste bits |
7 | AZH | Z akse akselerasjon 8 høyeste bits |
8 | TEMPL | Temperatur 8 laveste bits |
9 | TEMPH | Temperatur 8 høyeste bits |
10 | Sum | Sjekksum |
Beregning
ax=((AxH<<8)|AxL)/32768*16*9.81
ay=((AyH<<8)|AyL)/32768*16*9.81
az=((AzH<<8)|AzL)/32768*16*9.81
Rotasjon
Blokker
Data | Innhold | Beskrivelse |
---|---|---|
0 | 0x55 | Pakke header |
1 | 0x52 | Rotasjon |
2 | WXL | X akse rotasjonshastighet 8 laveste bits |
3 | WXH | X akse rotasjonshastighet 8 høyeste bits |
4 | WYL | Y akse rotasjonshastighet 8 laveste bits |
5 | WYH | Y akse rotasjonshastighet 8 høyeste bits |
6 | WZL | Z akse rotasjonshastighet 8 laveste bits |
7 | WZH | Z akse rotasjonshastighet 8 høyeste bits |
8 | TEMPL | Temperatur 8 laveste bits |
9 | TEMPH | Temperatur 8 høyeste bits |
10 | Sum | Sjekksum |
Beregning
wx=((WxH<<8)|WxL)/32768*2000
wy=((WyH<<8)|WyL)/32768*2000
wz=((WzH<<8)|WzL)/32768*2000
Retning
Blokker
Data | Innhold | Beskrivelse |
---|---|---|
0 | 0x55 | Pakke header |
1 | 0x53 | Vinkelpakke |
2 | RollXL | X akse vinkel 8 laveste bits |
3 | RollXH | X akse vinkel 8 høyeste bits |
4 | PitchYL | Y akse vinkel 8 laveste bits |
5 | PitchYH | Y akse vinkel 8 høyeste bits |
6 | YawZL | Z akse vinkel 8 laveste bits |
7 | YawZH | Z akse vinkel 8 høyeste bits |
8 | TEMPL | Temperatur 8 laveste bits |
9 | TEMPH | Temperatur 8 høyeste bits |
10 | Sum | Sjekksum |
Beregning
wx=((RollxH<<8)|RollxL)/32768*180
wy=((PitchyH<<8)|PitchyL)/32768*180
wz=((YawzH<<8)|YawzL)/32768*180
Kode
Koden kan lastes ned herfra: https://github.com/kjetilfjellheim/micropython-sen0386
def readSensorValues(uart):
data = uart.read(BUFFER_SIZE)
if data is not None and len(data) == BUFFER_SIZE:
accPacket = data[ACCPACKET_BUFFER_START:ACCPACKET_BUFFER_END]
angVelPacket = data[ANGVELPACKET_BUFFER_START:ANGVELPACKET_BUFFER_END]
angPacket = data[ANGPACKET_BUFFER_START:ANGPACKET_BUFFER_END]
ax, ay, az, wx, wy, wz, roll, pitch, yaw = handlePackets(accPacket, angVelPacket, angPacket)
return ax, ay, az, wx, wy, wz, roll, pitch, yaw
else:
return UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED
Her leser vi sensor verdiene fra uart koblingen. Vi deler så buffer verdiene inn i data objektet og deler det i de forskjellige pakkene.
def handlePackets(accPacketData, angVelPacketData, angPacketData):
ax, ay, az = handleAccPacket(accPacketData)
wx, wy, wz = handleAngVelPacket(angVelPacketData)
roll, pitch, yaw = handleAngPacket(angPacketData)
return ax, ay, az, wx, wy, wz, roll, pitch, yaw
Her kaller vi de individuelle prosedyrene for de forskjellige pakkene.
def handleAccPacket(accPacketData):
if len(accPacketData) == PACKET_LENGTH and accPacketData[BYTE_PACKET_HEADER] is PACKET_HEADER and accPacketData[BYTE_PACKET_TYPE] is ACC_PACKET_HEADER:
ax = (CALCULATION_GRAVITY_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(accPacketData, BYTE_AXH_DATA_CONTENT, BYTE_AXL_DATA_CONTENT)
ay = (CALCULATION_GRAVITY_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(accPacketData, BYTE_AYH_DATA_CONTENT, BYTE_AYL_DATA_CONTENT)
az = (CALCULATION_GRAVITY_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(accPacketData, BYTE_AZH_DATA_CONTENT, BYTE_AZL_DATA_CONTENT)
return ax, ay, az
else:
return UNDEFINED, UNDEFINED ,UNDEFINED
Her beregner vi aksellerasjonene i de forskjellige aksene. Formulene for dette finner du lenger oppe.
def handleAngVelPacket(angVelPacketData):
if len(angVelPacketData) == PACKET_LENGTH and angVelPacketData[BYTE_PACKET_HEADER] is PACKET_HEADER and angVelPacketData[BYTE_PACKET_TYPE] is ANGVEL_PACKET_HEADER:
wx = (CALCULATION_ROTATION_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(angVelPacketData, BYTE_WXH_DATA_CONTENT, BYTE_WXL_DATA_CONTENT)
wy = (CALCULATION_ROTATION_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(angVelPacketData, BYTE_WYH_DATA_CONTENT, BYTE_WYL_DATA_CONTENT)
wz = (CALCULATION_ROTATION_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(angVelPacketData, BYTE_WZH_DATA_CONTENT, BYTE_WZL_DATA_CONTENT)
return wx, wy, wz
else:
return UNDEFINED, UNDEFINED , UNDEFINED
Her beregner vi rotasjonshastighet.
def handleAngPacket(angPacketData):
if len(angPacketData) == PACKET_LENGTH and angPacketData[BYTE_PACKET_HEADER] is PACKET_HEADER and angPacketData[BYTE_PACKET_TYPE] is ANG_PACKET:
roll = (CALCULATION_ANGLE_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(angPacketData, BYTE_ROLLH_DATA_CONTENT, BYTE_ROLLL_DATA_CONTENT)
pitch = (CALCULATION_ANGLE_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(angPacketData, BYTE_PITCHH_DATA_CONTENT, BYTE_PITCHL_DATA_CONTENT)
yaw = (CALCULATION_ANGLE_CONSTANT / MAX_16_BIT_INTEGER_SIZE) * convertShort(angPacketData, BYTE_YAWH_DATA_CONTENT, BYTE_YAWL_DATA_CONTENT)
return roll, pitch, yaw
return UNDEFINED, UNDEFINED, UNDEFINED
Beregner vinkel i de forskjellige aksene.
def convertShort(packet, highByte, lowByte):
b = bytearray(2)
b[0] = packet[highByte]
b[1] = packet[lowByte]
result = ustruct.unpack(">h", b)[0]
return result
Dette er den viktige delen for å konvertere to byte til en short. En short er besår av to bytes.
Hex | Binær |
D7 | 11010111 |
F8 | 11111000 |
Høy byte | Lav byte | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
1=Negativ/0=Positiv | -10247 | ||||||||||||||
(180 / 32768) * -10247 = -56.28 |