当前位置:网站首页>【GO记录】从零开始GO语言——用GO语言做一个示波器(二)基于arduino的简易示波器
【GO记录】从零开始GO语言——用GO语言做一个示波器(二)基于arduino的简易示波器
2022-08-03 02:19:00 【创客协会的阿蛋°】
演示视频
用TinyGO语言做一个基于arduino的简易示波器
原理
原理就是用arduino获取高低电平模拟值的跳变,这就是示波器的电压值了,然后再来判断跳变的时间,来达到获取PWM或者触发信号的效果。
理论上应该用定时器加外部中断会比较号一点,但是我在TinGo中没找到定时器计时和外部中断的代码,所以就没做出来,然后arduino的时钟频率实在太低了,才16M。
示例代码地址:https://tinygo.org/docs/reference/microcontrollers/machine/bluepill/
思路
/* *思路:PWM波形是这样的: *__ __ __ * |__| |__| *我只需要捕获上升沿以及下降沿、周期的时间就可以计算出他的频率了 *电压使用ADC中获取的数值就可以了 */
代码
package main
import (
"machine" //支持包
"time" //时间函数
)
//变量
var (
//串口变量
uart = machine.Serial
tx = machine.UART_TX_PIN
rx = machine.UART_RX_PIN
sensor machine.ADC
//自定义变量
//时间变量
OS_time uint64
last_time uint64
now_time uint64
sys_time time.Time
delay1s uint64 = 1000000000
led_test_time uint64 = 0
Pwm_time [10]uint64
Pwm_Down uint64
Pwm_Rise uint64
//电压变量
Vol_times int
voltage uint16 = 0
Vol_arr [5]uint16
Vol_default uint16
Vol_Down uint16
Vol_Rise uint16
Last_Vol_Rise uint16
)
//调试代码
func My_time() {
sys_time := time.Now()
now_time = sys_time.Nsec1() //现在的计数周期 速度是16M 实际上测试并不准确
OS_time = (now_time - last_time) //单位:10ns 精度在百微秒级
last_time = now_time
// println(now_time)
//println(sys_time.Nanosecond())
//println(OS_time) //系统运行周期所占时间
}
func led_test(led machine.Pin) {
led_time := (now_time - led_test_time)
if led_time > delay1s*2 {
led.High()
led_test_time = now_time
//print("\r\nledtime:")
//print(led_test_time)
print("\r\n")
/* for i := 0; i <= Vol_times; i++ { print("\r\n") print(i) print(":") print(Vol_arr[i]) }*/
print("\r\n")
} else {
// println(now_time - led_test_time)
// println(led_test_time)
led.Low()
}
}
func main() {
//led引脚初始化 PD13
led := machine.LED
led.Configure(machine.PinConfig{
Mode: machine.PinOutput})
//串口1波特率:9600
uart.Configure(machine.UARTConfig{
TX: tx, RX: rx})
uart.Write([]byte("UART_init BaudRate:9600\r\n"))
//ADC初始化
machine.InitADC()
sensor = machine.ADC{
machine.ADC0}
sensor.Configure(machine.ADCConfig{
}) //配置 参考电压、转换bit、单次采样次数 16bit:(0--5V)min=0 x=65535
voltage := sensor.Get() //获取电压值
uart.Write([]byte("\r\nvol:")) //打印电压
print(voltage)
sys_time := time.Now() //获取时间值
last_time = sys_time.Nsec1() //获取纳秒
led_test_time = last_time
uart.Write([]byte("\r\nsys_time:")) //打印时间
print(last_time)
for {
//获取系统时间
My_time()
//获取ADC
//AD_Sample() //电压采样调试
AD_Pwm_Sample(sensor) //PWM捕获
//led_test(led)
}
}
func AD_Sample() {
voltage := sensor.Get()
//str1 := strconv.Itoa(int(voltage)) //整转串 方便打印
//println("adc0:" + str1)
voltage1 := uint32(voltage)
voltage1 = ((voltage1 * 1000) / 65472) * 5 //此公式为 ((ADC的模拟值电压*精度)/转换bit)*参考电压 bit原理上应该为65535 但是实测5V时只有65472
voltage = uint16(voltage1 / 1)
//str1 = strconv.Itoa(int(voltage)) //整转串 方便打印
//println("vol:" + str1)
println(voltage)
Vol_arr[Vol_times] = voltage
println(Vol_arr[Vol_times])
if Vol_times >= 99 {
Vol_times = 0
} else {
Vol_times++
}
//uart.Write([]byte("\r\nvol:"))
//print(voltage)
}
func AD_Sample2() (v uint16) {
voltage := sensor.Get()
voltage1 := uint32(voltage)
voltage1 = ((voltage1 * 1000) / 65472) * 5 //此公式为 ((ADC的模拟值电压*精度)/转换bit)*参考电压 bit原理上应该为65535 但是实测5V时只有65472
voltage = uint16(voltage1 / 1) //可取精度1~1000 1000时单位为V
//println(voltage)
return voltage
}
/* *思路:PWM波形是这样的: *__ __ __ * |__| |__| *我只需要捕获上升沿以及下降沿、周期的时间就可以计算出他的频率了 *电压使用ADC中获取的数值就可以了 */
func AD_Pwm_Sample(sen machine.ADC) {
i := 0
for {
voltage = AD_Sample2()
//print("\r\nVol:")
//print(voltage)
//第一次上升沿
if voltage > 4990 {
//如果电压大于5000mV 默认触发电平为5000
sys_time = time.Now()
Pwm_time[0] = sys_time.Nsec1() //记录现在的时间
Vol_arr[0] = voltage //记录现在的电压值
//记录PWM中第一次下降沿时间
for {
voltage = AD_Sample2() //获取电压
if voltage < 130 {
//如果电压小于30mv(防止BUG,本应该是0v)
sys_time = time.Now()
Pwm_time[1] = sys_time.Nsec1() //记录现在的时间
Vol_arr[1] = voltage //记录现在的电压值
break // 退出for循环
}
}
//记录PWM中第二次上升沿的时间
for {
voltage = AD_Sample2() //获取电压
if voltage > 4990 {
//如果电压大于3000mV
sys_time = time.Now()
Pwm_time[2] = sys_time.Nsec1() //记录现在的时间
Vol_arr[2] = voltage //记录现在的电压值
i = 1
break // 退出for循环
}
}
}
if i == 1 {
Vol_default = Vol_arr[0]
Vol_Down = Vol_arr[1]
Vol_Rise = Vol_arr[2]
Pwm_Down = (Pwm_time[1] - Pwm_time[0]) / 1000000 //下降沿时间 单位是ms
Pwm_Rise = (Pwm_time[2] - Pwm_time[0]) / 1000000 //上升沿时间 单位是ms
//软件debug
Pwm_time[3] = Pwm_Rise
Pwm_time[4] = Pwm_time[3]
Pwm_time[5] = Pwm_time[4]
Pwm_time[6] = Pwm_time[5]
Pwm_time[7] = Pwm_time[6]
if Pwm_time[3] == Pwm_time[4] {
if Pwm_time[4] == Pwm_time[5] {
if Pwm_time[5] == Pwm_time[6] {
if Pwm_time[6] == Pwm_time[7] {
//Last_Vol_Rise = Vol_Rise
print_debug()
break
}
}
}
}
/* if Vol_Rise != Last_Vol_Rise { flag++ if flag >= 50 { //如果检测的脉冲总时长变化 需要检测50次才可确认 以此滤波 防止干扰信号 flag = 0 Last_Vol_Rise = Vol_Rise } } else if Vol_Rise == Last_Vol_Rise { //Last_Vol_Rise = Vol_Rise flag = 0 print_debug() break }*/
}
}
}
func print_debug() {
print("\rVol:")
print(voltage)
print(" Pwm_Down:")
print(Pwm_Down)
print(" Pwm_Rise:")
print(Pwm_Rise)
print(" Pwm:")
print(Pwm_Down * 100 / Pwm_Rise)
print(" ")
}
其实本质上和C++开发没什么区别,只不过GO语言的易用性和规范性,相当于其他语言,更简洁高效一些。
边栏推荐
- 问题记录:jenkins构建时报错The goal you specified requires a project to execute but there is no POM in...
- 【TA-霜狼_may-《百人计划》】美术2.5 模型常见问题及规范
- leetcode:163 缺失的区间
- Mysql-如何进行慢SQL查询
- 部门之间,互不信任正常吗?(你是否遇到过)
- 超级复杂可贴图布局的初级智能文本提示器
- 【静态类型和动态类型 编译检查和运行检查 Objective-C中】
- Incorrect datetime value: ‘2022-01-01‘ for function str_to_date
- DTD约束和Schema约束
- 一个循环,两个循环问题的思考及复现
猜你喜欢
随机推荐
常见钓鱼手法及防范
Incorrect datetime value: ‘2022-01-01‘ for function str_to_date
韦东山 数码相框 项目学习(五)libjpeg-turbo的移植
Useful Monitoring Scripts What you want part1 in Oracle
FLIR E95 在8层楼看马路上行驶的CAR的热成像形态?
在排列中求lcs
超级复杂可贴图布局的初级智能文本提示器
46LVS+Keepalived群集
WordPress博客问答小插件
initramfs详解----设备文件系统
国标GB28181协议EasyGBS平台项目现场通知消息过多导致系统卡顿该如何解决?
LabVIEW程序框图保存为图像
Topic Modeling of Short Texts: A Pseudo-Document View
openCV第二篇
”QSqlDatabasePrivate::removeDatabase: connection ‘test-connect‘ is still in use“数据库多次打开报错
思维+启发式合并
数据中台建设(八):数据服务体系建设
MySQL里获取当前周、月、季的第一天/最后一天
monkey 压测
Summary of some interviews