0

I am using a raspberry pi4 with an IMU 6050 sensor and would like to save the data in a csv file with a frequency of 200 saples / s. I use a button to close the file and open a new one. However, the sampling rate is unstable and lower than 200 samples / s. Can you help me? Thanks in advance

image of frequency

import smbus            #import SMBus module of I2C
from time import sleep          #import
import datetime
import time
import numpy as np
import csv
import sys
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#some MPU6050 Registers and their Address
PWR_MGMT_1   = 0x6B
SMPLRT_DIV   = 0x19
CONFIG       = 0x1A
GYRO_CONFIG  = 0x1B
INT_ENABLE   = 0x38
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
ACCEL_ZOUT_H = 0x3F
GYRO_XOUT_H  = 0x43
GYRO_YOUT_H  = 0x45
GYRO_ZOUT_H  = 0x47
ACCEL_CONFIG = 0x1C
GYRO_CONFIG  = 0x1B

# Scale Modifiers
ACCEL_SCALE_MODIFIER_2G = 16384.0
ACCEL_SCALE_MODIFIER_4G = 8192.0
ACCEL_SCALE_MODIFIER_8G = 4096.0
ACCEL_SCALE_MODIFIER_16G = 2048.0

GYRO_SCALE_MODIFIER_250DEG = 131.0
GYRO_SCALE_MODIFIER_500DEG = 65.5
GYRO_SCALE_MODIFIER_1000DEG = 32.8
GYRO_SCALE_MODIFIER_2000DEG = 16.4

# Pre-defined ranges
ACCEL_RANGE_2G = 0x00
ACCEL_RANGE_4G = 0x08
ACCEL_RANGE_8G = 0x10
ACCEL_RANGE_16G = 0x18

GYRO_RANGE_250DEG = 0x00
GYRO_RANGE_500DEG = 0x08
GYRO_RANGE_1000DEG = 0x10
GYRO_RANGE_2000DEG = 0x18



f = open(time.strftime("%Y%m%d-%H%M%S")+'_Datalog.csv','w')
f.write('Time(ms),Ax(g),Ay(g),Az(g),Gx(°/s),Gy(°s),Gz(°/s),"\n')

delta = 0
start_time = (time.time()*1000)

def MPU_Init():
    #write to sample rate register
    bus.write_byte_data(Device_Address, SMPLRT_DIV, 7)
    
    #Write to power management register
    bus.write_byte_data(Device_Address, PWR_MGMT_1, 1)
    
    #Write to Configuration register
    bus.write_byte_data(Device_Address, CONFIG, 0)
    
    #Write to Gyro configuration register
    bus.write_byte_data(Device_Address, GYRO_CONFIG, 24)
    
    #Write to interrupt enable register
    bus.write_byte_data(Device_Address, INT_ENABLE, 1)
    
    #Write accelerometer range
    
    bus.write_byte_data(Device_Address,ACCEL_CONFIG ,0x00)
    bus.write_byte_data(Device_Address,ACCEL_CONFIG ,ACCEL_RANGE_2G)
    #Write Gyro range
    bus.write_byte_data(Device_Address,GYRO_CONFIG ,0x00)
    bus.write_byte_data(Device_Address,GYRO_CONFIG ,GYRO_RANGE_250DEG)

def read_raw_data(addr):
    #Accelero and Gyro value are 16-bit
        high = bus.read_byte_data(Device_Address, addr)
        low = bus.read_byte_data(Device_Address, addr+1)
    
        #concatenate higher and lower value
        value = ((high << 8) | low)
        
        #to get signed value from mpu6050
        if(value > 32768):
                value = value - 65536
        return value

bus = smbus.SMBus(1)    # or bus = smbus.SMBus(0) for older version boards
Device_Address = 0x68   # MPU6050 device address

MPU_Init()

print (" Reading Data of Gyroscope and Accelerometer")

while True:
        
       
 millis = (time.time()*1000)
 
 delta  = np.uint32(millis - start_time)
 #Read Accelerometer raw value
 acc_x = read_raw_data(ACCEL_XOUT_H)
 acc_y = read_raw_data(ACCEL_YOUT_H)
 acc_z = read_raw_data(ACCEL_ZOUT_H)
        
 #Read Gyroscope raw value
 gyro_x = read_raw_data(GYRO_XOUT_H)
 gyro_y = read_raw_data(GYRO_YOUT_H)
 gyro_z = read_raw_data(GYRO_ZOUT_H)
        
 #Full scale range +/- 250 degree/C as per sensitivity scale factor
 #Full scale range +/- 250 degree/C as per sensitivity scale factor
 Ay = -acc_x/ACCEL_SCALE_MODIFIER_2G
 Ax = acc_y/ACCEL_SCALE_MODIFIER_2G
 Az = -acc_z/ACCEL_SCALE_MODIFIER_2G
     
 Gy = gyro_x/GYRO_SCALE_MODIFIER_250DEG
 Gx = -gyro_y/GYRO_SCALE_MODIFIER_250DEG
 Gz = gyro_z/GYRO_SCALE_MODIFIER_250DEG
 

 f.write(str(delta) + ',' + str(Ax) + ',' + str(Ay) + ',' + str(Az) + ',' + str(Gx) + ',' + str(Gy) + ',' + str(Gz) +'\n')
    
       
        
 sleep(0.005)
 input_state      = GPIO.input(25)       
        #n_packet = n_packet +1;

 if input_state == False:

   sleep(1)
   print("Done")
   
    #pickle.dump(record,f)
   f.close()
   
   SystemExit
   input_state == True
   f = open(time.strftime("%Y%m%d-%H%M%S")+'_Datalog.csv','w')
   start_time = (time.time()*1000)
  • `sleep()` was never built to be a high-precision tool. Beyond that, you'll want to move the data collection and the writing into two separate threads so new data can be collected while other data is being written. – Charles Duffy Jul 25 '20 at 20:43
  • Frankly, though, Python is altogether the wrong language to use for any kind of task with real-time requirements. – Charles Duffy Jul 25 '20 at 20:44
  • One place to start while you _are_ sticking with Python, though, would be [looping at a constant rate with high precision for signal sampling](https://stackoverflow.com/questions/26774186/looping-at-a-constant-rate-with-high-precision-for-signal-sampling). – Charles Duffy Jul 25 '20 at 20:44

0 Answers0