This repository has been archived by the owner on Oct 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
wt.c
221 lines (183 loc) · 5.49 KB
/
wt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
* This file is an MPU6050 demonstration.
* https://openest.io/en/2020/01/21/mpu6050-accelerometer-on-raspberry-pi/
* Copyright (c) 2020 Julien Grossholtz - https://openest.io.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#define MPU6050_I2C_ADDR 0x68
#define REG_ACCEL_ZOUT_H 0x3F
#define REG_ACCEL_ZOUT_L 0x40
#define REG_PWR_MGMT_1 0x6B
#define REG_ACCEL_CONFIG 0x1C
#define REG_SMPRT_DIV 0x19
#define REG_CONFIG 0x1A
#define REG_FIFO_EN 0x23
#define REG_USER_CTRL 0x6A
#define REG_FIFO_COUNT_L 0x72
#define REG_FIFO_COUNT_H 0x73
#define REG_FIFO 0x74
#define REG_WHO_AM_I 0x75
int file = -1;
// Please note, this is not the recommanded way to write data
// to i2c devices from user space.
void i2c_write(__u8 reg_address, __u8 val) {
char buf[2];
if(file < 0) {
perror("Error, i2c bus is not available");
exit(1);
}
buf[0] = reg_address;
buf[1] = val;
if (write(file, buf, 2) != 2) {
perror("Error, unable to write to i2c device");
exit(1);
}
}
// Please note, this is not thre recommanded way to read data
// from i2c devices from user space.
char i2c_read(uint8_t reg_address) {
char buf[1];
if(file < 0) {
printf("Error, i2c bus is not available\n");
exit(1);
}
buf[0] = reg_address;
if (write(file, buf, 1) != 1) {
printf("Error, unable to write to i2c device\n");
exit(1);
}
if (read(file, buf, 1) != 1) {
printf("Error, unable to read from i2c device\n");
exit(1);
}
return buf[0];
}
uint16_t merge_bytes( uint8_t LSB, uint8_t MSB) {
return (uint16_t) ((( LSB & 0xFF) << 8) | MSB);
}
// 16 bits data on the MPU6050 are in two registers,
// encoded in two complement. So we convert those to int16_t
int16_t two_complement_to_int( uint8_t LSB, uint8_t MSB) {
int16_t signed_int = 0;
uint16_t word;
word = merge_bytes(LSB, MSB);
if((word & 0x8000) == 0x8000) { // negative number
signed_int = (int16_t) -(~word);
} else {
signed_int = (int16_t) (word & 0x7fff);
}
return signed_int;
}
int main(int argc, char *argv[]) {
int adapter_nr = 1; /* probably dynamically determined */
char bus_filename[250];
char accel_x_h,accel_x_l,accel_y_h,accel_y_l,accel_z_h,accel_z_l,temp_h,temp_l;
uint16_t fifo_len = 0;
int16_t x_accel = 0;
int16_t y_accel = 0;
int16_t z_accel = 0;
int16_t temp = 0;
float x_accel_g, y_accel_g, z_accel_g, temp_f;
snprintf(bus_filename, 250, "/dev/i2c-1", adapter_nr);
file = open(bus_filename, O_RDWR);
if (file < 0) {
perror("file");
/* ERROR HANDLING; you can check errno to see what went wrong */
exit(1);
}
if (ioctl(file, I2C_SLAVE, MPU6050_I2C_ADDR) < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
perror("ioctl");
exit(1);
}
i2c_write(REG_PWR_MGMT_1, 0x01);
i2c_write(REG_ACCEL_CONFIG, 0x00);
i2c_write(REG_SMPRT_DIV, 0x07);
i2c_write(REG_CONFIG, 0x00);
i2c_write(REG_FIFO_EN, 0x88);
i2c_write(REG_USER_CTRL, 0x44);
// while(1) {
// static float pos = 0;
// static float ppppp = 0;
// char h = i2c_read(0x43);
// char l = i2c_read(0x44);
// uint16_t t = two_complement_to_int(h, l);
// //printf("0x%08x", t);
// float f = ((float) t)/16384;
// pos += f-1;
// //printf("pos %f", pos);
// //printf("\n");
// if (f-ppppp > 0.5 || f-ppppp < -0.5) {
// //printf("%f", f);
// printf("f %f\t%d", f, ppppp);
// printf("\n");
// //ppppp += f-1;
// ppppp = f;
// }
// // ppppp = f;
// //printf("%d ", t);
// }
// exit(0);
while(1) {
accel_x_h = i2c_read(REG_FIFO_COUNT_L);
accel_x_l = i2c_read(REG_FIFO_COUNT_H);
fifo_len = merge_bytes(accel_x_h,accel_x_l);
//printf("fifo len:%i", fifo_len);
if(fifo_len == 1024) {
//printf("fifo overflow !\n");
i2c_write(REG_USER_CTRL, 0x44);
break;
continue;
}
if(fifo_len >= 8) {
char bufffff[400];
for (int i=0;i<4; i++) {
char a = i2c_read(REG_FIFO);
char b = i2c_read(REG_FIFO);
int16_t t = two_complement_to_int(a, b);
printf("0x%08x ", t);
}
printf("\r");
//accel_x_h = i2c_read(REG_FIFO);
//accel_x_l = i2c_read(REG_FIFO);
//accel_y_h = i2c_read(REG_FIFO);
//accel_y_l = i2c_read(REG_FIFO);
//accel_z_h = i2c_read(REG_FIFO);
//accel_z_l = i2c_read(REG_FIFO);
//temp_h = i2c_read(REG_FIFO);
//temp_l= i2c_read(REG_FIFO);
//x_accel= two_complement_to_int(accel_x_h,accel_x_l);
//x_accel_g = ((float) x_accel)/16384;
//y_accel= two_complement_to_int(accel_y_h,accel_y_l);
//y_accel_g = ((float) y_accel)/16384;
//z_accel= two_complement_to_int(accel_z_h,accel_z_l);
//z_accel_g = ((float) z_accel)/16384;
//temp = two_complement_to_int(temp_h, temp_l);
//temp_f = (float)temp/340 + 36.53; // calculated as described in the MPU60%) register map document
//printf("x_gyro %.3fg y_gyro %.3fg z_accel %.3fg temp=%.1fc \r", x_accel_g, y_accel_g, z_accel_g, temp_f);
} else {
usleep(10000);
}
}
return 0;
}