计划赶不上变化

导航

项目流水账

新的工作要开始接触stm32,之前虽然也跟着别的项目有所接触,但是没有自己从头到尾做过一遍,现在要一个人抗下所有了,只能自学,希望能遇到所有的问题,把stm32学完。

项目需求,用移远的ec600U模组和stm32实现数据的采集和上传  只是暂时的会不断更新。

用到的模块:ec600U  stm32l010f4p6  mpu6050  w25q128 lc29h暂时只有这么多

因为硬件还有没有把板子搞出来,只能暂时淘宝买各种模块去搭建一个类似的平台

给到的资源:ec600U模组   stm32l076rz   mpu6050    w25q128   l76k 

方案一:直接用移远的模组外挂这些sensor和flash,便宜又方便,开发量小。

方案二:stm32+移远模组    有点烦人,做的事比较多。

 

方案一:

第一个周末:LK76是移远的模组 可以完美的打通,也是2小时的事,但是到了mpu6050就遇到了问题,研究了移远模组的python api所谓的iic功能,调试了一整天只能读到一组不会改变的数据,尽管看了很久他的iic协议还是不行,我自信我的代码没有错。最后查了一下硬件图,发现mpu6050的模组上拉的是3.3V的电,但是移远模组上拉要求1.8V的电,应该就是这个出了问题,无奈先放弃。

第二天,加载flash模组提供了spi的接口,但是读写的时候还是出了问题,有了之前mpu6050的经验我直接去看硬件的上拉,结果一样一个是3.3V一个是1.8V.没办法剩下的时间只能看看模组提供的api学习学习。看到EC600N有挂载文件的接口,但是EC600U没有,咨询了一下移远的技术支持,他们说ram太小了放不下这个接口。提出用eeprom去存,但是考虑到数据要存的比较多,可能不够所以直接放弃方案一,白瞎了2天,只调通了一个L76K。

贴一下调成功的代码记录一下,

import net
import utime
from machine import UART
import ure
import log
import utime
import _thread
from machine import Pin
from machine import UART

log.basicConfig(level=log.NOTSET)  # 设置日志输出级别
log = log.getLogger("Grey")  # 获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象

fixFlag = 0
stattus = None
GNSS_Baud = 1
state = 1
readnum = 600


gpio1 = Pin(Pin.GPIO1, Pin.OUT, Pin.PULL_DISABLE, 0)
if GNSS_Baud == 1:
    uart = UART(UART.UART1, 9600, 8, 0, 1, 0)
elif GNSS_Baud == 2:
    uart = UART(UART.UART1, 115200, 8, 0, 1, 0)
else:
    uart = UART(UART.UART1, 9600, 8, 0, 1, 0)

def uart_read():
    log.debug("uart_read start!")
    global state
    global readnum

    # while 1:
    while readnum:
        msgLen = uart.any()  # 返回是否有可读取的数据长度
        if msgLen:  # 当有数据时进行读取
            readnum -= 1
            msg = uart.read(msgLen)
            utf8_msg = msg.decode()  # 初始数据是字节类型(bytes),将字节类型数据进行编码
            if "Usart End" in utf8_msg:
                break
            else:
                log.info("---------------start-----------------")
                log.info("uart_read msg: {}".format(utf8_msg))
                log.info("---------------end-------------------")
        else:
            utime.sleep_ms(1)
            continue
    state = 0
    log.debug("uart_read end!")


'''
 * 参数1:端口 
        注:EC100YCN平台与EC600SCN平台,UARTn作用如下
        UART0 - DEBUG PORT
        UART1 – BT PORT
        UART2 – MAIN PORT   
        UART3 – USB CDC PORT
 * 参数2:波特率
 * 参数3:data bits  (5~8)
 * 参数4:Parity  (0:NONE  1:EVEN  2:ODD)
 * 参数5:stop bits (1~2)
 * 参数6:flow control (0: FC_NONE  1:FC_HW)
'''


def uart_write():
    log.debug("uart_write start!")
    count = 3
    # 配置uart
    while count:
        count -= 1
        utime.sleep(1)

        if GNSS_Baud == 1:
            write_msg = "$PCAS01,5*19\r\n".format(count)  # 115200波特率
        elif GNSS_Baud == 2:
            write_msg = "$PCAS01,1*1D\r\n".format(count)  # 9600波特率
        else:
            write_msg = "$PCAS01,5*19\r\n".format(count)  # 115200波特率

        uart.write(write_msg)  # 发送数据
        log.info("{}".format(write_msg))
    log.debug("uart_write end!")


def run():
    log.debug("run start!")
    _thread.start_new_thread(uart_read, ())  # 创建一个线程来监听接收uart消息
    _thread.start_new_thread(uart_write, ())  # 创建一个线程来监听执行uart_write函数
    log.debug("run end!")

class GnssGetData:
    # GPS数据采集及解析
    def __init__(self, uartn, baudrate, databits, parity, stopbits, flowctl):
        if uartn == 0:
            UARTN = UART.UART0
        elif uartn == 1:
            UARTN = UART.UART1
        elif uartn == 2:
            UARTN = UART.UART2
        elif uartn == 3:
            UARTN = UART.UART3
        else:
            UARTN = UART.UART1
        self.uart = UART(UARTN, baudrate, databits, parity, stopbits, flowctl)
        write_msg = "$PCAS03,1,1,1,1,1,1,1,1,0,0,,,0,0*02\r\n".format()  # 115200波特率
        uart.write(write_msg)
        utime.sleep(3)  # Delay to read data stability

    # 读取GNSS数据并加以解析
    def read_gnss_data(self):
        try:
            buf = self.uart.read(self.uart.any())
            gps_data = buf.decode().strip("b")
            print("gps_data:",gps_data,"\n")
            self.r = ure.search("GNGGA(.+?)M", gps_data)
            print("self.r:",self.r,"\n")
            self.r1 = ure.search("GNRMC(.+?)M", gps_data)
            print("self.r1:",self.r1,"\n")
            self.r2 = ure.search("GPGSV(.+?)M", gps_data)
            print("self.r2:",self.r2,"\n")
            self.r3 = ure.search("GNVTG(.+?)M", gps_data)
            print("self.r3:",self.r3,"\n")
            global fixFlag
            if self.r1.group(0).split(",")[2] == 'A':  # 有效定位
                fixFlag = 1
            else:
                fixFlag = 0
        except:
            print("Exception:read gnss data error!!!!!!!!")
            raise

    # 获取GPS模块是否定位成功
    @staticmethod
    def isfix():
        global fixFlag
        return fixFlag

    # 获取GPS模块定位的经纬度信息
    def get_location(self):
        if self.isfix() is 1:
            lat = float(self.r.group(0).split(",")[2]) // 100 + float(
                float(float(self.r.group(0).split(",")[2]) % 100) / 60)  #
            lat_d = self.r.group(0).split(",")[3]  #
            log = float(self.r.group(0).split(",")[4]) // 100 + float(
                float(float(self.r.group(0).split(",")[4]) % 100) / 60)  #
            log_d = self.r.group(0).split(",")[5]  #
            return lat, lat_d, log, log_d
        else:
            return None

    # 获取GPS模块授时的UTC时间
    def get_utc_time(self):
        return self.r.group(0).split(",")[1]

    # 获取GPS模块定位模式
    def get_location_mode(self):
        if self.r.group(0).split(",")[6] is '0':
            # print('定位不可用或者无效')
            return 0
        if self.r.group(0).split(",")[6] is '1':
            # print('定位有效,定位模式:GPS、SPS 模式')
            return 1
        if self.r.group(0).split(",")[6] is '2':
            # print('定位有效,定位模式: DGPS、DSPS 模式')
            return 2

    # 获取GPS模块定位使用卫星数量
    def get_used_sate_cnt(self):
        return self.r.group(0).split(",")[7]

    # 获取GPS模块定位可见卫星数量
    def get_viewed_sate_cnt(self):
        return self.r2.group(0).split(",")[3]

    # 获取GPS模块定位方位角 范围:0~359。以真北为参考平面。
    def get_course(self):
        return self.r2.group(0).split(",")[6]

    # 获取GPS模块对地速度(单位:KM/h)
    def get_speed(self):
        if self.r1.group(0).split(",")[7] == '':
            return None
        else:
            return float(self.r1.group(0).split(",")[7]) * 1.852

    # 获取GPS模块定位大地高(单位:米)
    def get_geodetic_height(self):
        return self.r.group(0).split(",")[9]

    def showtime():
        net.nitzTime()
        local_time = utime.localtime()
        stattus = '{0:0>4d}-{1:0>2d}-{2:0>2d} {3:0>2d}:{4:0>2d}:{5:0>2d}'.\
        format(local_time[0], local_time[1], local_time[2], local_time[3], local_time[4], local_time[5])
        print(stattus)
        utime.sleep(1)

下面是成功拿到的数据

gps_data: $GNGGA,083542.000,2807.70328,N,12059.06939,E,1,06,2.2,114.8,M,13.0,M,,*4B
$GNGLL,2807.70328,N,12059.06939,E,083542.000,A,A*46
$GNGSA,A,3,07,08,21,27,,,,,,,,,5.9,2.2,5.5,1*34
$GNGSA,A,3,26,35,,,,,,,,,,,5.9,2.2,5.5,4*3A
$GPGSV,2,1,05,01,34,181,,07,48,311,19,08,62,004,31,21,61,149,24,0*69
$GPGSV,2,2,05,27,34,038,32,0*58
$BDGSV,1,1,02,26,79,358,29,35,64,032,31,0*7E
$GNRMC,083542.000,A,2807.70328,N,12059.06939,E,0.00,315.13,030222,,,A,V*0F
$GNVTG,31
5.13,T,,M,0.00,N,0.00,K,A*26
$GNZDA,083542.000,03,02,2022,00,00*43
$GPTXT,01,01,01,ANTENNA OPEN*25
$GNGGA,083543.000,2807.70321,N,12059.06946,E,1,06,2.2,114.8,M,13.0,M,,*4B
$GNGLL,2807.70321,N,12059.06946,E,083543.000,A,A*46
$GNGSA,A,3,07,08,21,27,,,,,,,,,5.9,2.2,5.5,1*34
$GNGSA,A,3,26,35,,,,,,,,,,,5.9,2.2,5.5,4*3A
$GPGSV,2,1,05,01,34,181,,07,48,311,19,08,62,004,31,21,61,149,24,0*69
$GPGSV,2,2,05,27,34,038,32,0*58
$BDGSV,1,1,02,26,79,358,29,35,64,032,31,0*7E
$GNRMC,083543.000,A,28
07.70321,N,12059.06946,E,0.00,315.13,030222,,,A,V*0F
$GNVTG,315.13,T,,M,0.00,N,0.00,K,A*26
$GNZDA,083543.000,03,02,2022,00,00*42
$GPTXT,01,01,01,ANTENNA OPEN*25
$GNGGA,083544.000,2807.70314,N,12059.06954,E,1,06,2.2,114.9,M,13.0,M,,*48
$GNGLL,2807.70314,N,12059.06954,E,083544.000,A,A*44
$GNGSA,A,3,07,08,21,27,,,,,,,,,5.9,2.2,5.5,1*34
$GNGSA,A,3,26,35,,,,,,,,,,,5.9,2.2,5.5,4*3A
$GPGSV,2,1,05,01,34,181,,07,48,311
,19,08,62,004,31,21,61,149,24,0*69
$GPGSV,2,2,05,27,34,038,32,0*58
$BDGSV,1,1,02,26,79,358,29,35,64,032,31,0*7E
$GNRMC,083544.000,A,2807.70314,N,12059.06954,E,0.00,315.13,030222,,,A,V*0D
$GNVTG,315.13,T,,M,0.00,N,0.00,K,A*26
$GNZDA,083544.000,03,02,2022,00,00*45
$GPTXT,01,01,01,ANTENNA OPEN*25
$GNGGA,083545.000,2807.70311,N,12059.06960,E,1,06,2.2,114.9,M,13.0,M,,*4B
$GNGLL,2807.70311,N,12059.06960,E,083545.000,A,A*47

self.r: <match num=2>

self.r1: <match num=2>

self.r2: <m
atch num=2>

self.r3: <match num=2>

获取GPS模块是否定位成功:1(0表示失败,1表示成功)
获取GPS模块授时的UTC时间:083542.000
获取GPS模块定位模式:1(0表示定位不可用或者无效,1表示GPS、SPS 模式,2表示DGPS、DSPS 模式)
获取GPS模块定位使用卫星数量:06
获取GPS模块定位的经纬度信息:(28.12838800000001, 'N', 1
20.9844898333333, 'E')
获取GPS模块定位可见卫星数量:05
获取GPS模块定位方位角 范围:0~359。以真北为参考平面:181
获取GPS模块定位大地高:114.8米
获取GPS模块对地速度:0.0KM/h

 

时间线------------------------------------------------------------------------------------------------------------------2022/1/15

方案二:

第二个周末:之前没怎么做过stm32就要从头学一遍,真是苦了我。

1.首先要学习stm32cubemx去构建代码。https://www.bilibili.com/video/BV1m7411d78e?spm_id_from=333.999.0.0 这个小白教程还可以大致入门了,构建好了代码。

2.安装keil5.27 这个之前项目做过直接拿安装包装一下。但是下载pack是真的慢,https://blog.csdn.net/simon223/article/details/105090189 这个网址可以下载很多需要的包真是福音,Keil.STM32L0xx_DFP.2.2.0.pack 这个包是必下的。

3.https://blog.csdn.net/weixin_42741212/article/details/106220998 按照这个博客搞完然后编译一把,就差烧录验证了。

4.买了个正版stlink 血亏80。然后就是非常蛋疼的环节了。折磨了4个小时。

一开始这里什么都没有,然后add也找不到对应的stm32,然后安装了一个pack,Keil.STM32L0xx_DFP.2.2.0.pack 应该就是这个,然后选对device后,add才会有正确的选项。花费2小时。

然后更加坑爹的来了

 

st的评估板上留了一个jtag的接口,当然选择jtag去烧了简单方遍,然后就出现了上图,不管怎么调试,改驱动都无法正常使用jtag。折磨了半小时,我想起了提示的这句话在stm32 F0和L0上JTAG不可用,不知道是内部有设置还是什么的,直接放弃了jtag,用的

 

 swd。https://blog.csdn.net/praguejing/article/details/107596701参考这个博客接好线。stlink就能搜索到接口了,直接一把入魂,小灯闪了,泪流满面。搭环境4小时,烧录验证1分钟。

5.第一个模块mpu6050.

下载了淘宝正点原子哥的xxx战舰代码。好家伙居然是标准库写的,一看我的代码是hal库的,直接没软用。就去百度淘https://blog.csdn.net/dodwind/article/details/88624941这个博客非常好,简洁明了。

https://github.com/Heimerdingerzzz/MPU6050 直接下载代码。好像都搞好了,佩服做32的资源就是多。

https://www.zhihu.com/tardis/sogou/art/191646577  这个博客是如何把DMP添加进编译  不管有没有用先添加起来。

https://blog.csdn.net/he__yuan/article/details/76559569?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param 这个博客是如何引用mpu6050.c的函数方法说了一下。暂时先把初始化先简单编译一遍。

报错了 .\test1\test1.axf: Error: L6218E: Undefined symbol hi2c1 (referred from inv_mpu.o).

原来是没有添加iic的接口 

遇到小插曲 为什么在芯片引脚上设置iic会是single mapped signals 是因为后面的connectivity没有打开iic 我真是小白。

编译成功。今天就这样吧 太雷人了。明天再验。

时间线------------------------------------------------------------------------------------------------------------------2022/1/21

 

今天初三了,电脑修好了但是stm32的miniusb线丢了,先暂时不搞stm32,先把ec600u先研究一下。

ec600u发送数据给腾讯云,然后小程序腾讯练练接收腾讯云发送的数据。也就是mqtt的订阅和数据接收

选择腾讯云是因为之前买了个

点击新建项目

 

 

点击新建产品

 

 

 点击自己新建的产品

 

 新建自定义功能,比如当前的是板子上的aht10温湿度传感器

 

 

然后一直下一步到设备调试 新建一个设备

 

微信搜索小程序 腾讯连连 然后扫描上面设备的二维码

都创建好了以后去下载mqtt-fx,如下的博客https://blog.csdn.net/tiantang_1986/article/details/85101366

 然后下载https://iot-exp-individual-1258344699.cos.ap-guangzhou.myqcloud.com/password%E7%94%9F

%E6%88%90%E5%B7%A5%E5%85%B7.zip?_ga=1.48325030.1621947844.1600674791
点击sign.html
这是登录账号和密码的生成器。
把设备的信息输进去就可以得到登录帐号和密码。然后打开mqtt-fx,

 

 点击connect 显示绿色就表示连接成功。然后看到腾讯云上的设备也显示在线。

 

 

上报后拿到右边的调试日志

 

 

 然后把这个放到mqtt-fx内

 

 然后publish 就可以在腾讯练练的设备里看到对应的改变了,其他的功能我先不研究。

然后把当前的ec600u板子上带的aht10的数据传到腾讯小程序上。

import log 
import ujson 
import utime 
import _thread 
from machine import I2C 
import utime as time 
from TenCentYun import TXyun 
import checkNet 
from misc import Power 




productID = r"QOE7J6I5SH" # 产品标识 
devicename = r"test" # 设备名称 
devicePsk = r"spLipjbdCp62dPk+D1rH3A==" # 设备密钥(一型一密认证此参数传入 None) 
ProductSecret = None # 产品密钥(一机一密认证此参数传入 None) 
# 输入发布 Topic 
DEF_TOPIC_PUB = r"$thing/up/property/{}/{}".format(productID, devicename) 
# 输入订阅 Topic 
DEF_TOPIC_SUB = r"$thing/down/property/{}/{}".format(productID, devicename) 
CLIENT_TOKEN_STR = "7df3c076-40e1-49e4-8689-2a11df7dc1c3" 

PROJECT_NAME = "QuecPython_TencentYun_example"
PROJECT_VERSION = "1.0.0"

checknet = checkNet.CheckNetwork(PROJECT_NAME, PROJECT_VERSION)

log.basicConfig(level=log.INFO)
txyun_log = log.getLogger("TenCentYun")

class aht10class():
	i2c_dev = None 
	i2c_addre = None # Initialization command 
	AHT10_CALIBRATION_CMD = 0xE1 # Trigger measurement 
	AHT10_START_MEASURMENT_CMD = 0xAC # reset 
	AHT10_RESET_CMD = 0xBA 
	def write_data(self, data):
		self.i2c_dev.write(self.i2c_addre, bytearray(0x00), 0, bytearray(data), len(data)) 
		pass 
	def read_data(self, length): 
		r_data = [0x00 for i in range(length)] 
		r_data = bytearray(r_data) 
		self.i2c_dev.read(self.i2c_addre, bytearray(0x00), 0, r_data, length, 0)
		return list(r_data) 
	def aht10_init(self, addre=0x38): 
		self.i2c_dev = I2C(I2C.I2C1, I2C.STANDARD_MODE) # 返回 i2c 对象 
		self.i2c_addre = addre 
		self.sensor_init() 
		pass 
	def aht10_transformation_temperature(self, data): 
		r_data = data 
		temperature = ((r_data[2] & 0xf) << 16) | ( r_data[3] << 8) | r_data[4] 
		temperature = (temperature * 200.0 / (1 << 20)) - 50 
		I2C_log.info( "current temp is {0}°C".format( round( temperature, 1))) 
		return temperature 
	def aht10_transformation_humidity(self, data): 
		r_data = data # 根据数据手册的描述来转化温度 
		humidity = (r_data[0] << 12) | ( r_data[1] << 4) | ((r_data[2] & 0xF0) >> 4) 
		humidity = (humidity / (1 << 20)) * 100.0 
		I2C_log.info( "current humi is {0}%".format( round( humidity, 1))) 
		return humidity
	def sensor_init(self): 
	# calibration 
		self.write_data([self.AHT10_CALIBRATION_CMD, 0x08, 0x00]) 
		time.sleep_ms(300) # at last 300ms 
		pass 
	def ath10_reset(self): 
		self.write_data([self.AHT10_RESET_CMD]) 
		time.sleep_ms(20) # at last 20ms 
	def Trigger_measurement(self, val): 
	# Trigger data conversion 
		self.write_data([self.AHT10_START_MEASURMENT_CMD, 0x33, 0x00]) 
		time.sleep_ms(200) # at last delay 75ms 
		# check has success 
		r_data = self.read_data(6) 
		# check bit7 
		if (r_data[0] >> 7) != 0x0: 
			I2C_log.info("Conversion has error") 
		else:
			temp = self.aht10_transformation_temperature(r_data[1:6]) 
			humi = self.aht10_transformation_humidity(r_data[1:6]) 
			val[0] = round(temp, 1) 
			val[1] = round(humi, 1) 
def network_checknet(): 
	while True: 
		try: 
			checknet.wait_network_connected(30) 
			utime.sleep_ms(2000) 
			txyun_log.info('network_checknet ... ...') 
		except BaseException: 
			txyun_log.info('network_checknet: Not Net, Resatrting...') 
			utime.sleep_ms(200) 
			Power.powerRestart() 
def sub_cb(topic, msg): 
	# 云端消息响应回调函数 
	TXyun_log.info("subscribe recv:") 
	TXyun_log.info(topic.decode(), msg.decode()) 
def main1():
		tenxun = TXyun(productID, devicename, devicePsk, ProductSecret) # 创建连接对象 
		tenxun.setMqtt() 
		tenxun.setCallback(sub_cb)
		tenxun.subscribe(DEF_TOPIC_SUB)
		tenxun.start() 
		# i2c_obj = I2C(I2C.I2C0, I2C.STANDARD_MODE) # 返回 i2c 对象 
		ath_dev = aht10class() 
		ath_dev.aht10_init() 
		while True: 
			val = [0, 1] 
			ath_dev.Trigger_measurement(val) 
			send_data = ''' {{"clientToken": "{}", "method": "report", "params": {{ "lac": 0, "cid": 0, "mnc": 0, "mcc": 0, "networkType": 1,"temp": {}, "shidu": {} }} }}'''.format(CLIENT_TOKEN_STR, val[0], val[1]) 
			send_data = ujson.loads(send_data) 
			s = ujson.dumps(send_data) 
			TXyun_log.info(s) 
			tenxun.publish(DEF_TOPIC_PUB, s) 
			utime.sleep_ms(2000) 
if __name__ == "__main__": 
	log.basicConfig(level=99) 
	CheckNet_log = log.getLogger("CheckNet") 
	TXyun_log = log.getLogger("TXyun_log") 
	I2C_log = log.getLogger("AHT10") 
	checknet = checkNet.CheckNetwork(PROJECT_NAME, PROJECT_VERSION)
	checknet.poweron_print_once() 
		
	try: 
		checknet.wait_network_connected(30) 
		_thread.start_new_thread(network_checknet, ()) 
	except BaseException: 
		CheckNet_log.info('Not Net, Resatrting...') 
		utime.sleep_ms(200) 
		Power.powerRestart() 
	txyun_log.info('txyun_log.info   yepc   over ')
	print('print yepc   over ')
	main1()

 今天就这样了 ,晚上看看如何自己搭建一个mqtt服务器。

时间线------------------------------------------------------------------------------------------------------------------2022/2/3

先加一个简单的printf打印,之前一直没加。初始化一个uart然后把这个huart1对应的加进去就好了。

#include <stdio.h>

/* USER CODE BEGIN 4 */
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
/* USER CODE END 4 */

 

 时隔一个月,入职也一个月了。都做的差不多了,又临时要修改方案了,真是操蛋,之前做的也只是项目的预热,板子一出来全都不一样了,fuck。

板子还是没到,但是还是叫我提前写代码,然后板子到了再调试。

先总结一下之前的做的把。

第一版 mpu6050+ec600U+w25q128+l76k  mpu6050和w25q128在stm32上,l76k在ec600u上。

第二版 mpu6050+ec600U+w25q128+l76k 把外部传感器全部接到了 stm32上,剩下ec600u和stm32通信 ,要解决l76k和stm32的工作

第三版 L26-DR+ec600U+w25q128 把外部传感器全部接到了 stm32上,剩下ec600u和stm32通信    直接给我换了个gps的芯片,然后imu的芯片也去掉了L26-DR自带imu。这个是最终的版本。终于定下来~~

这个星期前几天还在弄mpu6050的dmp的问题,搞了2天好了,结果不要了。

先记录一下这个 

mpu6050 之前做的能读到7个原始数据了,说明通了,现在搞姿态处理。

有2种方法 1是姿态融合需要自己去写算法,网上案例有参考一下就好了,但是对性能有点要求需要点算力。2是dmp,一个官方提供的黑盒子把,数据原始数据就可以得到姿态,移植一下就好了。

吐槽:这里当然是想用dmp的,简单移植一下就好了,但是当时这个printf一直是坏了,mpu_dmp_init初始化的时候一直卡住了 也不知道哪里有问题,一开始是以为dmp_load_motion_driver_firmware卡在这里了百度了很多有什么说中断,什么速度设置什么的,一直搞不定,卡了一天后来printf弄好了,加了点打印再试了一下,可以dmp_load_motion_driver_firmware成功了,但是这个过程非常非常非常慢,然后卡在自检这里,因为是接的模块杜邦线各种接根本不能稳定,然后干脆直接跳过自检等正式板子到,最后可以拿到姿态数据了,千辛万苦本来高高兴兴终于搞完一个模块,结果最终板子出来说直接用L26-DR,不用imu了。我直接气炸。这2天白忙活了。

至于或者融合算法我之前也是dmp一直初始化失败也是焦虑得半夜睡不着查到的。

https://www.zhihu.com/tardis/sogou/art/228805569 这个博客有说,还挺详细挺好。最后dmp能用了就直接用dmp了。这种算法什么的对工程研究起来简直浪费时间。

更新玩之前的

现在就是重新开始第三版了  蓝受..... 只给了我2周去搞代码,说2周后机子到了就要快速搞好。这周白瞎了2天就3天的时间做w25q128.

之前因为ec600u不支持外挂w25q128,导致我后面也没有去看这个,由于L26-DR暂时没有芯片,之前也没有搞过类似gps的芯片,那个l76k也是用的现成的代码,看了下文档决定,先做简单的flash。

w25q128基于stm32的例子网上例子非常多,写的好点的也就原子哥的,不过他那个不是hal写的,想直接拿过来用也比较麻烦

还好找到了个博客写的还不错

http://www.mcublog.cn/stm32/2021_01/stm32cubemx-spi-flash-w25q128/ 这个基本实现简单的读写。

涉及到的源码github是https://github.com/nimaltd/w25qxx 用的这个大叔的代码,后面fatfs的时候还改了不少。。。。

上面的都通了以后,就是要加一个管理flash的小系统了,这个我选择了一个比较小巧的fatfs。

网上找了很多的例子,还是一头雾水不知道怎么去修改,就看了下面的几个博客,很多的博客都没有讲到位最终移植部位在哪里。起码要把w25q128的什么初始化,读写接口给移植进去把,但是具体的都没有详细讲到,但是最后还是有个比较好的让我看到了关键点 就是第一篇这个讲的比较好,能让人通俗易懂。

1.https://blog.csdn.net/redeemer_Qi/article/details/108644860
2.https://blog.csdn.net/weixin_42653531/article/details/103745344
3.https://blog.csdn.net/qq_39772670/article/details/109824810

4.https://www.cnblogs.com/cage666/p/9178326.html

最关键的就是这几个初始化读写的移植,发现上面那个w25qxx的源码和上面这篇参考的这篇博客的函数名不一样,这就麻烦了鬼知道他用的是那个源码,但是直觉应该是正点原子的,然后看了一下果然,名字一点都不差的,但是正点原子的并不是单纯的w25q128的驱动源码,里面还添加了什么gpio的配置什么的。再加上我之前用的那个代码已经调通了能简单读写了,没办法只能看正点原子的代码用当前的代码去封装读写函数。就剩最后编译了。还是个大坑。

就是去配置ffconfig.h的时候。我也不看了直接按照博客的去配置,结果出现了如下的报错

newpro\newpro.axf: Error: L6218E: Undefined symbol ff_convert (referred from ff.o).

百度了一下就说什么的都有,什么包含头文件啊参数传递错误声明函数什么的。可能也是夜深了,突然脑子一动,我先不按博客的修改试试呢,然后就出现了各种奇怪的报错,然后这个报错问题还是好解决的,最后正常的编译成功,后来我在不经意中看到了2.https://blog.csdn.net/weixin_42653531/article/details/103745344 这个文档的最后可改进的地方,可能是在自定义的头里面 有些变量会影响编译。然后我就暂时先编译过了,等下周一再去测试能不能行。

还有我看了一下L26-DR的几个文档,发现这个gps好像和别的gps返回的数据有点不一样的,如果只是和普通的gps芯片一样的化返回的也就那几个参数和数据,分析的源码我也在github参考的下了一份。千万要一样啊 ,不一样那就完犊子了。我一个人有点难受了。

后续:

1.检测一下这个存储能不能完成功能。下周一就知道了。

2.L26-DR这个芯片要在stm32上工作起来,参考的例子估计是没有了 要自己调了,先暂时拿l76k用着,但是好像这2个很多不一样,弄好了也没意义。这个感觉要被搞很久很久。

3.stm32和L26-DR的通信,用的是uart,这个简单,ec600u那边的uart收发的代码之前调试的都可以了。

4.还有就是把这个数据通过ec600u和mqtt传出去。这个暂时用腾讯云是可以的,但是目前具体要通过什么方式或者什么样的服务器还不知道,可以延后一下。

据说只有2个月的时间去实现,然后就我一个人做,咋看不多的东西,但是没有机器再加上我是个stm32的小白,之前也没做过这种项目,期间还有其他c++的东西叫我写,好苦啊~~~~

时间线------------------------------------------------------------------------------------------------------------------2022/3/5

 又来更新了,板子千呼万唤始出来,终于在上周五到了,出乎意料的坑,没有usb,只有一个sw的烧录接口,其他什么都没有了,stm32的芯片还给换了 导致后面出了大毛病。

遇到的问题:

1.没有和那种开发板一样把usb引出来,很多针脚都没有引出来,还要买漆包线,焊枪去飞线。(这个也能忍了)

2.因为之前写好的ec600u的代码是在开发板上的用的是python的版本,但是现在只留了串口,只能通过at指令去配置。(之前写的代码全部白瞎了)

3.l26-dr这个芯片也没有引出串口的针脚,目前是没有验证的方法,只能飞完线,然后通过电脑的串口去试验,没做过没啥经验,只能先试,再写。

 

首先遇到的问题就是没有usb接出来,导致异常不习惯,芯片换了stm32l010f4,flash和sram都是比较小的,关键是sram,只有2k导致后面的fatfs移植不上去,还有稍微申请一个大一点的buf就会编译不过。这2个都是血淋淋的教训,之前没做过也没往硬件上想,相信硬件会换一个和之前一样的32芯片,结果完全不是。

 

 

 

 

我在移植fatfs的时候一直以为是自己配置出现了问题,老编译不过,最后才想到硬件,去查了一下被坑了一晚上。最后fatfs这个就先不做了,等换芯片新板子到。

由于sram很小导致,创建接收gps的buf也只能建800bytes,信息都抓不全。

2.没有了usb,只能通过at指令去发送数据给ec600u。

硬件坚持不加usb,最终还是要用at写。心想一个测试板子这不加那不加的,又没有最后定版。

大概查了一下AT指令,意思就是通过串口发送指令给芯片。解决的思路,首先用电脑串口去模拟实现mqtt的功能,然后再用代码实现。

博客参考 https://www.cnblogs.com/asnail/p/12810359.html  简单的AT指令的讲解,再加上FAE提供的文档。

暂时配置成这样。后来试了一下,只配置后面的也可以。

AT+CESQ
AT+CGATT?
AT+QMTCFG="version",0,4
AT+QMTCFG="pdpcid",0,3
AT+QMTCFG="ssl",0,0,0
AT+QMTCFG="keepalive",0,60
AT+QMTCFG="session",0,0
AT+QMTCFG="timeout",0,20,3,1
AT+QMTCFG="will",0,0
AT+QMTCFG="recv/mode",0,0
AT+QMTCFG="qmtping",0,10
AT+QMTCFG="send/mode",0,0

----------------------------------------------------------

AT+QMTOPEN=0,"101.34.201.128",1883
AT+QMTCONN=0,"6ba02edb371340278a329fde1a6ed37e"
AT+QMTSUB=0,1,"topic/pub",0
AT+QMTPUBEX=0,1,0,0,"topic/pub",10

这里卡了很久,因为在输入AT+QMTOPEN=0,"101.34.201.128",1883后要赶紧输入AT+QMTCONN=0,"6ba02edb371340278a329fde1a6ed37e" 否则会导致链路层错误,卡了我整整2小时。当连上去的那一刹那,整个人都舒服了。

电脑串口成功了,那代码就灰常简单了。

uint8_t at0[]="at\r\n"; 
uint8_t at1[]="AT+QMTOPEN=0,\"101.34.201.128\",1883\r\n";
uint8_t at2[]="AT+QMTCONN=0,\"6ba02edb371340278a329fde1a6ed37e\"\r\n";
uint8_t at3[]="AT+QMTSUB=0,1,\"topic/pub\",0\r\n";
uint8_t at4[]="AT+QMTPUBEX=0,1,0,0,\"topic/pub\",10\r\n";
uint8_t buf[]="yepc hello word\r\n";

HAL_UART_Transmit(&huart2, at0,sizeof(at0)-1,0xffff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2, at1,sizeof(at1)-1,0xffff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2, at2,sizeof(at2)-1,0xffff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2, at3,sizeof(at3)-1,0xffff);

memset(at4,0,sizeof(at4));
sprintf(&at4[0],"AT+QMTPUBEX=0,1,0,0,\"topic/pub\",%d\r\n",sizeof(buf)-1);
HAL_UART_Transmit(&huart2, at4,sizeof(at4)-1,0xffff);
//printf("sizeof:%d\r\n",sizeof(at4)-1);
HAL_Delay(200);
HAL_UART_Transmit(&huart2, buf,sizeof(buf)-1,0xffff);

这样就成了 因为没有拿到具体要传的东西,现在通了,就先放着了。等具体需求下来了再完善下。

3.就剩最后一个gps模块了。

因为没有飞线我现在也没有稳定连上串口去修改配置,但是出厂是有配置的

 

 这样我就读到了数据,大致就下面的样子

$PSTMDRSENMSG,30,3291759960,428,-1941,16468*0C
$PSTMDRSENMSG,31,3291759960,-67,158,8*06
$PSTMDRSENMSG,30,3291828170,429,-1946,16460*02
$PSTMDRSENMSG,31,3291828170,57,-76,35*06
$PSTMDRSENMSG,30,3291896364,413,-1942,16474*08
$PSTMDRSENMSG,31,3291896364,36,30,18*23
$PSTMDRSENMSG,30,3291964557,406,-1940,16464*05
$PSTMDRSENMSG,31,3291964557,-59,27,-17*29
$PSTMDRSENMSG,30,3292032772,411,-1938,16469*0D
$PSTMDRSENMSG,31,3292032772,20,-68,17*0D
$PSTMDRSENMSG,30,3292100983,423,-1955,16461*0F
$PSTMDRSENMSG,31,3292100983,-28,-95,-5*34
$PSTMDRSENMSG,30,3292169305,406,-1945,16477*05
$PSTMDRSENMSG,31,3292169305,-57,45,-14*27
$GPRMC,205125.000,V,0000.00078,S,00000.00072,E,,,060924,,,N*69
$GPGGA,205125.000,0000.00078,S,00000.00072,E,0,00,99.0,-12.93,M,0.0,M,,*6F
$GPVTG,,T,,M,,N,,K,N*2C
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GPGLL,0000.00078,S,00000.00072,E,205130.000,V,N*53
$PSTMANTENNASTATUS,-1,0,0,0*7D
$PSTMDRCONFID,100.16,100.16,182.3160,0.1145,0.00,0.5669,0.000602,0.050000,100.0000,100.2,100.2,-1.6,0.0*1F
$PSTMDRGPS,-0.000013071,0.000012036,0.00000,0.00000,99.000,99.000,99.000,0.000,0.000,0.00000,-12.9*42
$PSTMDRSTEP,15,1.64763,0.00173,0,0,1.000,1.000,1*2F
$PSTMDRSTYPE,3*58
$PSTMDRUPD,0.0,0.0,1.1,0.00,-1.955,0.000,-0.000002,0.000000,0.0*75
$PSTMDRSTATE,3295170100,-0.0000041,-0.0000062,-0.32,0.00,1.6483,0.7582,0.02290,-0.000002,0.000000,-12.9*61
$PSTMDRCAL,0,0,0,0,ff,1,1,N*0C
$PSTMDRAHRS,-13.0,5.8,0.0,14.000,0.425,0.0*20
$PSTMDRGNSA,0,0,0,0,0,0.00,0.00,0.00,0.00,0.00,21.00,10.00,0.10,35.00*0C
$PSTMDREPE,141.42,-1.00*72
$PSTMDRDEBUG,-1.0,2.0,0.3,0.0,0.0,0.0*70

然后查了一下资料,据说只要用到$GPGGA和$GPRMC 就可以得到定位的信息。等飞完线就把其他的都关掉,就开这2个还有PSTMDRSENMSG

然后就是分析数据,这个我在GitHub上找到了代码

https://github.com/yhuan416 当个参考把。感觉如果只有2-3个字段的话就不麻烦了。
现在就差飞线了。有点磨拳擦掌的感觉。
 
时间线------------------------------------------------------------------------------------------------------------------2022/3/29
 好久没更新了,好像能调的模块都调完了,各个模块也全都搞一起了,完结撒花。
 
 

 

posted on 2022-01-21 22:27  张培粉  阅读(570)  评论(0编辑  收藏  举报