2019年3月6日-KS103的使用

本文记录了作者在使用KS103超声波模块时遇到的数据波动问题及解决过程。通过官方详细的手册,作者采用模拟IIC方式并进行多模块测试。在发现模块并联时通信不稳定后,排查硬件,发现IIC接口上拉电阻过大,更换为4.7K后问题得到解决。

这个之前用过来,但是由于当时测量数据波动就放在一边了,今天想起来又试了一试成功了。

就是这个模块,当然我用的是IIC的;

其实官方的计数说明书写的极其详细;

此程序来自官网教程,在模拟IIC接口,并且硬件无问题的情况下,多个模块同时运行测试通过;

4) STM32 CORTEX-3 ARM 主机模拟 I2C 通讯与 KS101B/KS103/KS103S 连接控制 C 代码
//单片机型号:STM32F103RBT //本程序未示出所有系统配置函数
#include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"
#include "delay.h"
u8 KS103_ReadOneByte(u8 address, u8 reg)
{
 u8 temp=0;

 IIC_Start();
 IIC_Send_Byte(address); //发送低地址
 IIC_Wait_Ack();
 IIC_Send_Byte(reg); //发送低地址
 IIC_Wait_Ack();
 IIC_Start();
 IIC_Send_Byte(address + 1); //进入接收模式
 IIC_Wait_Ack();
 delay_us(50); //增加此代码通信成功!!!
 temp=IIC_Read_Byte(0); //读寄存器 3
 IIC_Stop();//产生一个停止条件
 return temp;
}
void KS103_WriteOneByte(u8 address,u8 reg,u8 command)
{

 IIC_Start();
 IIC_Send_Byte(address); //发送写命令
 IIC_Wait_Ack();
 IIC_Send_Byte(reg);//发送高地址
 IIC_Wait_Ack();
 IIC_Send_Byte(command); //发送低地址
 IIC_Wait_Ack();
 IIC_Stop();//产生一个停止条件
}
void IIC_Init(void)
{
 RCC->APB2ENR|=1<<4;//先使能外设 IO PORTC 时钟
 GPIOC->CRH&=0XFFF00FFF;//PC11/12 推挽输出
 GPIOC->CRH|=0X00033000;
 GPIOC->ODR|=3<<11; //PC11,12 输出高
}
//产生 IIC 起始信号
void IIC_Start(void)
{
 SDA_OUT(); //sda 线输出
 IIC_SDA=1;
 IIC_SCL=1; 
delay_us(10);
 IIC_SDA=0;//START:when CLK is high,DATA change form high to low
 delay_us(10);
 IIC_SCL=0;//钳住 I2C 总线,准备发送或接收数据
}
//产生 IIC 停止信号
void IIC_Stop(void)
{
 SDA_OUT();//sda 线输出
 IIC_SCL=0;
 IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 delay_us(10);
 IIC_SCL=1;
 IIC_SDA=1;//发送 I2C 总线结束信号
 delay_us(10);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
 u8 ucErrTime=0;
 SDA_IN(); //SDA 设置为输入
 IIC_SDA=1;delay_us(6);
 IIC_SCL=1;delay_us(6);
 while(READ_SDA)
 {
 ucErrTime++;
 if(ucErrTime>250)
 {
 IIC_Stop();
 return 1;
 }
 }
 IIC_SCL=0;//时钟输出 0
 return 0;
}
//产生 ACK 应答
void IIC_Ack(void)
{
 IIC_SCL=0;
 SDA_OUT();
 IIC_SDA=0;
 delay_us(10);
 IIC_SCL=1;
 delay_us(10);
 IIC_SCL=0;
}
//不产生 ACK 应答
void IIC_NAck(void)
{
 IIC_SCL=0;
 SDA_OUT();
 IIC_SDA=1;
 delay_us(10);
 IIC_SCL=1;
 delay_us(10);
 IIC_SCL=0;
}
//IIC 发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答 
void IIC_Send_Byte(u8 txd)
{
 u8 t;
 SDA_OUT();
 IIC_SCL=0;//拉低时钟开始数据传输
 for(t=0;t<8;t++)
 {
 IIC_SDA=(txd&0x80)>>7;
 txd<<=1;
 delay_us(10);
 IIC_SCL=1;
 delay_us(10);
 IIC_SCL=0;
 delay_us(10);
 }
}
//读 1 个字节,ack=1 时,发送 ACK,ack=0,发送 nACK
u8 IIC_Read_Byte(unsigned char ack)
{
 unsigned char i,receive=0;
 SDA_IN();//SDA 设置为输入
 for(i=0;i<8;i++ )
 {
 IIC_SCL=0;
 delay_us(10);
 IIC_SCL=1;
 receive<<=1;
 if(READ_SDA)receive++;
 delay_us(5);
 }
 if (!ack)
 IIC_NAck();//发送 nACK
 else
 IIC_Ack(); //发送 ACK
 return receive;
}
int main(void)
{
 u16 range;
 Stm32_Clock_Init(9);//系统时钟设置
 delay_init(72); //延时初始化
 uart_init(72,9600); //串口 1 初始化
 while(1)
 {
 KS103_WriteOneByte(0XE8,0X02,0XB0);
 delay_ms(80);
 range = KS103_ReadOneByte(0xe8, 0x02);
 range <<= 8;
 range += KS103_ReadOneByte(0xe8, 0x03);
 }
}

程序采用模拟IIC的方式,很好移植,修改对应的IO口,然后将“IIC_Init()”加入到main函数中。

官网手册地址如下:http://www.dauxi.com/KS10X-V110_CN.pdf

使用过程中,出现用一个KS103一切正常,数据稳定

但是当用两个的时候,两个都不稳定了,当把其中任意一个模块的通讯线拔下去后,另一个恢复正常;

跟厂家技术沟通了下(厂家技术肖工人很好,非常感谢他的帮助),程序应该没问题,排查硬件接口,测量IIC接口上拉电阻,18K,远远高于正常IIC的上拉电阻4.7K

重新焊接两个4.7K的上拉电阻,数据稳定。

帮我看下这个框架对不对,让后如果要用lstm和xgboot混合模型来预测可以嘛?可以话怎么弄,另外加入jvquant的l2数据获取--- 1️⃣ 先把数据源跑通(最优先) 任务 目的 现成资源 ✅ 申请 MiniQMT 实盘权限 拿到真实行情 + 交易接口 找券商(国金、华鑫、中泰等)开通 QMT 实盘,勾选“量化接口” ✅ 用 xtquant 取到任意 1 只股票 1 天 1 分钟线 验证数据链路 `pip install xtquant` → 跑官方 demo:`from xtquant import xtdata; xtdata.download_history_data('000001.SZ', period='1m', start_time='20250724')` ✅ 用 akshare 补股东户数 弥补 MiniQMT 没有基本面 `pip install akshare` → `ak.stock_zh_a_gdhs(symbol="300539")` --- 2️⃣ 把“特征函数”写完整(第二步) 你现在缺的 3 个核心函数,我都给你补成可运行的雏形,先跑通再优化: ```python # file: zhuang_features.py from xtquant import xtdata import akshare as ak import pandas as pd import numpy as np def get_chip_density(code, end_date, n=90): """筹码集中度:90%成本区间 / 中位价""" bars = xtdata.get_market_data([code], end_time=end_date, count=n, period='1d')[code] closes = bars['close'].dropna() if len(closes) < n*0.8: return np.nan p90 = closes.quantile(0.95) # 90%分位 p10 = closes.quantile(0.05) p50 = closes.median() return (p90 - p10) / p50 def get_holder_change(code): """最近一期股东户数环比变化率""" try: df = ak.stock_zh_a_gdhs(symbol=code.replace('.SZ', '').replace('.SH', '')) # 取最近两期 latest = df.iloc[0]['股东户数'] prev = df.iloc[1]['股东户数'] return (latest - prev) / prev except: return np.nan def get_breakout(code, end_date): """最近是否缩量突破 20 新高""" bars = xtdata.get_market_data([code], end_time=end_date, count=20, period='1d')[code] vol = bars['volume'] price = bars['close'] vol_ratio = vol.iloc[-1] / vol.mean() is_high = price.iloc[-1] == price.max() return 1 if (vol_ratio < 0.8 and is_high) else 0 ``` --- 3️⃣ 把“训练样本”做出来(第三步) 任务 具体动作 ✅ 标注庄股 用 Excel 把历史上 20 只公认庄股(如 300539、002995、603123 等)在启动打标签 1,其余随机 200 只正常股打 0 ✅ 批量跑特征 用上面 3 个函数,把每只股票在启动前 1 天的特征都跑成 CSV,格式:`code,chip_density,holder_change,breakout,label` ✅ 存到 `dataset.csv` 后面 PyTorch 直接 `pd.read_csv('dataset.csv')` --- 4️⃣ 把“模型”写成可训练脚本(第四步) ```python # file: train_model.py import torch, pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('dataset.csv').dropna() X = torch.tensor(df[['chip_density','holder_change','breakout']].values, dtype=torch.float32) y = torch.tensor(df['label'].values, dtype=torch.float32).unsqueeze(1) X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2) class ZhuangNet(torch.nn.Module): def __init__(self): super().__init__() self.net = torch.nn.Sequential( torch.nn.Linear(3, 16), torch.nn.ReLU(), torch.nn.Linear(16, 1), torch.nn.Sigmoid() ) def forward(self, x): return self.net(x) model = ZhuangNet() opt = torch.optim.Adam(model.parameters(), 1e-3) criterion = torch.nn.BCELoss() for epoch in range(200): opt.zero_grad() loss = criterion(model(X_train), y_train) loss.backward() opt.step() if epoch % 20 == 0: with torch.no_grad(): val_loss = criterion(model(X_val), y_val) print(epoch, loss.item(), val_loss.item()) torch.save(model.state_dict(), 'zhuang_net.pt') ``` --- 5️⃣ 把“实时扫描”写成脚本(第五步) ```python # file: realtime_scan.py import torch, datetime, json, requests from zhuang_features import get_chip_density, get_holder_change, get_breakout model = ZhuangNet() model.load_state_dict(torch.load('zhuang_net.pt')) model.eval() codes = xtdata.get_stock_list_in_sector('沪深A股') today = datetime.datetime.today().strftime('%Y%m%d') found = [] for code in codes: try: f1 = get_chip_density(code, today) f2 = get_holder_change(code) f3 = get_breakout(code, today) if any(pd.isna([f1,f2,f3])): continue prob = model(torch.tensor([[f1,f2,f3]])).item() if prob > 0.8: found.append((code, round(prob,3))) except Exception as e: print(code, e) # 推送到企业微信机器人 webhook = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key' data = {"msgtype":"text","text":{"content": f"发现庄股候选:{found}"}} requests.post(webhook, json=data) ``` --- 6️⃣ 把“实盘执行”加一道保险(第六步) - ✅ 先用模拟盘跑 2 周,确认信号无未来函数(比如把 `end_date` 设成昨,再对比今天的实际走势)。 - ✅ 用 `schedule` 或 `crontab` 每天 14:50 自动跑一次,盘中不干扰。 - ✅ 加熔断:单只股票当成交额 < 5000 万直接跳过,避免流动性陷阱。 --- 7️⃣ 把“志 & 回测”补齐(最后一步) - ✅ 把每扫描结果写进 `sqlite` 或 `csv`,方便后续回测胜率。 - ✅ 用 `backtrader` 对 2023-2024 全市场跑一遍,看信号后 5 收益分布,确定最终阈值(可能 0.7 比 0.8 更好)。 --- 🚩一句话总结 你现在缺的只是“把骨架连上血肉的七步流程”。 按上面 1→7 的顺序逐条完成: 申请接口 → 补特征 → 造样本 → 训练 → 实时扫描 → 模拟盘 → 回测, 最终就能在 MiniQMT 上全自动跑起来。
07-27
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值