SEN0386 kommunikasjon micropython

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.

PacketStart Time (s)End Time (s)DataMax Voltage (V)Min Voltage (V)Voltage Pk-Pk (V)Packet Time (s)
10.05160.0527553.318-0.6753.9930.001042
20.05270.0537513.318-0.0563.3740.001042
30.05370.0547FD3.487-0.1123.5990.001042
40.05470.0558FF3.318-0.1123.4310.001042
50.05580.0568F73.487-0.4503.9370.001042
60.05680.0579FF3.431-1.5755.0050.001042
70.05790.05890F3.318-1.5754.8930.001042
80.05890.0599083.487-0.2253.7120.001042
90.05990.0610F33.374-0.1693.5430.001042
100.06100.0620093.262-1.5754.8370.001042
110.06200.0630AB3.262-0.6193.8810.001042
120.06300.0641553.431-1.4624.8930.001042
130.06410.0651524.5560.0004.5560.001042
140.06510.0662023.318-0.0563.3740.001042
150.06620.0672003.262-0.1123.3740.001042
160.06720.0682003.318-0.1123.4310.001042
170.06820.0693003.431-0.2253.6560.001042
180.06930.0703004.274-0.2814.5560.001042
190.07030.0714003.318-0.2253.5430.001042
200.07130.0724F33.318-0.2253.5430.001042
210.07240.0734093.262-0.2253.4870.001042
220.07340.0745A53.4310.0003.4310.001042
230.07450.0755553.824-0.0563.8810.001042
240.07550.0765533.824-0.7314.5560.001042
250.07650.0776CE3.431-0.1693.5990.001042
260.07760.0786FF3.431-0.1693.5990.001042
270.07860.07970D3.374-1.0124.3870.001042
280.07970.0807003.262-0.1693.4310.001042
290.08070.0817D73.712-0.6194.3300.001042
300.08170.0828F83.2620.0003.2620.001042
310.08280.0838683.2620.0003.2620.001042
320.08380.0848463.318-0.6193.9370.001042
330.08480.0859FF3.3180.0003.3180.001042
340.08590.086955-0.0560.001042
350.08690.0880543.318-1.9125.2300.001042
360.08800.0890003.318-0.6753.9930.001042
370.08900.0900003.318-0.2253.5430.001042
380.09000.0911003.262-0.1123.3740.001042
390.09110.0921003.318-0.0563.3740.001042
400.09210.0932003.2620.0003.2620.001042
410.09310.0942003.2620.0003.2620.001042
420.09420.0952003.262-0.1693.4310.001042
430.09520.0963003.318-0.1693.4870.001042
440.09630.0973A93.431-0.1693.5990.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

DataInnholdBeskrivelse
00x55Pakke header
10x51Akselerasjonspakke
2AXLX akse akselerasjon 8 laveste bits
3AXHX akse akselerasjon 8 høyeste bits
4AYLY akse akselerasjon 8 laveste bits
5AYHY akse akselerasjon 8 høyeste bits
6AZLZ akse akselerasjon 8 laveste bits
7AZHZ akse akselerasjon 8 høyeste bits
8TEMPLTemperatur 8 laveste bits
9TEMPHTemperatur 8 høyeste bits
10SumSjekksum

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

DataInnholdBeskrivelse
00x55Pakke header
10x52Rotasjon
2WXLX akse rotasjonshastighet 8 laveste bits
3WXHX akse rotasjonshastighet 8 høyeste bits
4WYLY akse rotasjonshastighet 8 laveste bits
5WYHY akse rotasjonshastighet 8 høyeste bits
6WZLZ akse rotasjonshastighet 8 laveste bits
7WZHZ akse rotasjonshastighet 8 høyeste bits
8TEMPLTemperatur 8 laveste bits
9TEMPHTemperatur 8 høyeste bits
10SumSjekksum

Beregning

wx=((WxH<<8)|WxL)/32768*2000
wy=((WyH<<8)|WyL)/32768*2000
wz=((WzH<<8)|WzL)/32768*2000

Retning

Blokker

DataInnholdBeskrivelse
00x55Pakke header
10x53Vinkelpakke
2RollXLX akse vinkel 8 laveste bits
3RollXHX akse vinkel 8 høyeste bits
4PitchYLY akse vinkel 8 laveste bits
5PitchYHY akse vinkel 8 høyeste bits
6YawZLZ akse vinkel 8 laveste bits
7YawZHZ akse vinkel 8 høyeste bits
8TEMPLTemperatur 8 laveste bits
9TEMPHTemperatur 8 høyeste bits
10SumSjekksum

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.

HexBinær
D711010111
F811111000
Høy byteLav byte
1101011111111000
1=Negativ/0=Positiv-10247
(180 / 32768) * -10247 = -56.28
Resultatet blir -56.28 grader