(들어가기전에->
1. 자이로센서는 MPU6050 사용하였습니다 )
(한국인이 좋아하는 결론부터 말하기)
자이로센서 값(데이터)를 전송하는 코드.
'''
Read Gyro and Accelerometer by Interfacing Raspberry Pi with MPU6050 using Python
http://www.electronicwings.com
'''
import smbus #import SMBus module of I2C
from time import sleep
#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
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)
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:
#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
Ax = acc_x/16384.0
Ay = acc_y/16384.0
Az = acc_z/16384.0
Gx = gyro_x/131.0
Gy = gyro_y/131.0
Gz = gyro_z/131.0
print ("Gx=%.2f" %Gx, u'\u00b0'+ "/s", "\tGy=%.2f" %Gy, u'\u00b0'+ "/s", "\tGz=%.2f" %Gz, u'\u00b0'+ "/s", "\tAx=%.2f g" %Ax, "\tAy=%.2f g" %Ay, "\tAz=%.2f g" %Az)
sleep(1) # 1초당 자이로센서 값 받아들임.
파일을 실행시키게 되면,
아래와 같이 터미널에 자이로센서 값이 출력이 된다.
☞ 출력값 의미
- Gx =도 / 초 단위의 자이로 X 축 데이터
- Gy =도 / 초 단위의 자이로 Y 축 데이터
- Gz =도 / 초 단위의 자이로 Z 축 데이터
- Ax = 가속도계 X 축 데이터 (g)
- Ay = 가속도계 Y 축 데이터 (g)
- Az = 가속도계 Z 축 데이터 (g)
<본판으로 들어와서 자이로 센서 값 MQTT를 이용해 전송을 해보자.>
-> 프린트로 사용한 부분을 단순히 변수로 받아주기만 하면 되는것이다.
1. Publisher Code
import smbus #import SMBus module of I2C
from time import sleep
import paho.mqtt.client as mqtt
#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
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)
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")
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("connected OK")
else:
print("Bad connection Returned code=", rc)
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_publish(client, userdata, mid):
print("In on_pub callback mid= ", mid)
client = mqtt.Client()
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.connect('111.111.111.119', 20518) # 접속하고 싶은 ip와 port번호 입력
while True:
#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
Ax = acc_x/16384.0
Ay = acc_y/16384.0
Az = acc_z/16384.0
Gx = gyro_x/131.0
Gy = gyro_y/131.0
Gz = gyro_z/131.0
data="%.2f " %Gx + "%.2f " %Gy + "%.2f " %Gz +"%.2f " %Ax + "%.2f " %Ay + "%.2f" %Az
client.publish('gyro', data,0)
sleep(0.2) # 0.2 초당 data가 전송됨.
client.disconnect()
참고) 1. 잘보면 data 변수 받는곳에 공백(space)이 있는데 이것은 내가 subscribe코드에서 공백을 기준으로 DB에 담기
때문이다.
2. 자이로 센서값을 굳이 확실하게 다 받을 필요가 없어 QOS level 0으로 설정함.
2. Subscriber Code
(이 코드에는 DB사용 부분이 없습니다)
별거없다. 그냥 pub와 동일한 '토픽명', 'QOS level'만 설정해주면 된다.
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("connected OK")
else:
print("Bad connection Returned code=", rc)
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_subscribe(client, userdata, mid, granted_qos):
print("subscribed: " + str(mid) + " " + str(granted_qos))
def on_message(client, userdata, msg):
print(str(msg.payload.decode("utf-8")))
# 새로운 클라이언트 생성
client = mqtt.Client()
# 콜백 함수 설정 on_connect(브로커에 접속), on_disconnect(브로커에 접속중료), on_subscribe(topic 구독),
# on_message(발행된 메세지가 들어왔을 때)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_subscribe = on_subscribe
client.on_message = on_message
# address : localhost, port: 20518 에 연결
client.connect('localhost', 20518)
client.subscribe('gyro', 0)
#print(data)
client.loop_forever()
3. 결과창
---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ----------------
아래서 부터는 DB에 저장하는 Subscriber 코드이다. (PostgreSQL 사용)
<DB저장 하는 방법.>
1. Publisher Code는 위와 동일함.
2. DB저장 Subscriber code
import paho.mqtt.client as mqtt
import psycopg2 as db # DB용 모듈
from datetime import datetime # 시간 함수
import time
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("connected OK")
else:
print("Bad connection Returned code=", rc)
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_subscribe(client, userdata, mid, granted_qos):
print("subscribed: " + str(mid) + " " + str(granted_qos))
def on_message(client, userdata, msg):
print(str(msg.payload.decode("utf-8")))
##index명으로 시간으로 받기 위해 시간을 만들어주는 부분
now = datetime.now()
timestr = time.strftime("%m%d-%H%M%S") # 초까지 나옴
timestr_2=timestr + str(now.microsecond) # 마이크로 초까지 출력하기위함. (초당5개 받음으로)
## DB에 데이터 전송(postgreSQL 대문자 사용 X)
# gyro_value 라는 테이블 / column_name = time(index),gx,gy,gz,ax,ay,az
query2 = "insert into gyro_value (time,gx,gy,gz,ax,ay,az) values(%s,%s,%s,%s,%s,%s,%s)"
value=str(msg.payload.decode("utf-8")).split(" ") # split함수 쓰면 list로 변형됨.
data=(timestr_2,value[0],value[1],value[2],value[3],value[4],value[5])
cur.execute(query2,data)
conn.commit()
conn_string="dbname='get_gyro_data' host='localhost' user='kick' password='a1234!'" # DB 설정시 했던 값.
conn=db.connect(conn_string)
cur=conn.cursor()
# 새로운 클라이언트 생성
client = mqtt.Client()
# 콜백 함수 설정 on_connect(브로커에 접속), on_disconnect(브로커에 접속중료), on_subscribe(topic 구독),
# on_message(발행된 메세지가 들어왔을 때)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_subscribe = on_subscribe
client.on_message = on_message
# address : localhost, port: 20518 에 연결
client.connect('localhost', 20518)
# gyro topic 으로 메세지 발행
client.subscribe('gyro',0)
client.loop_forever()
<코드설명>
기본적인 MQTT코드부분은 생략을 하겠다.
query2 라는 부분은 위의 주석을 보면 코드를 이해할수 있을거고 (그냥 저렇게 쓰는것 같더라....)
value = ~ 부분은 우리가 아까 publisher 코드에서 공백(space)를 기준으로 데이터를 받았음으로 split(" ")을 함으로
받았던 6개의 값들이 공백을 기준으로 리스트를 생성하게 된다.
data= 시간,gx,gy,gz,ax,ay,az 을 담게되고
cur.excute 를 함으로 DB에 전송을 하게 된다.
conn_string 은 본인들이 DB설정했던 값들을 그대로 해주면 된다.
3 결과창.
서버측에서 받은 값들이 출력이 됨과 동시에
아래와 같이 DB테이블에 저장이 됨을 확인할 수 있다.
(아마 터미널창에 있는 위에 3개의 행들은 내가 DB 에서 삭제해서 없는듯...)
'프로그래밍 > MQTT' 카테고리의 다른 글
[Python] MQTT를 이용한 GPS 값 전송 (raspberry pi 이용) (0) | 2022.09.05 |
---|---|
[Python] MQTT를 이용한 이미지 전송 (raspberry pi 이용) (0) | 2022.08.29 |
[Python] MQTT 통신하기(docker,rabbitmq사용) (0) | 2022.08.12 |
(4) MQTT.fx 사용하기 (0) | 2022.03.01 |
(3) 파이썬에서 MQTT 사용하기. (0) | 2022.03.01 |