当前位置:网站首页>【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语言的易用性和规范性,相当于其他语言,更简洁高效一些。
边栏推荐
猜你喜欢
在VScode里调试ROS程序
Postman如何做接口自动化测试?
Summary of some interviews
Go新项目-编译项目的细节(4)
The LVS load balancing cluster and the deployment of the LVS - NAT experiment
WordPress博客问答小插件
C语言——-动态内存开辟与管理(malloc,free,calloc,realloc)+柔性数组
韦东山 数码相框 项目学习(五)libjpeg-turbo的移植
QCheckBox、margin、border、pandding、QHoxLayout、QSplitter、QSpacerItem
Wei Dongshan Digital Photo Frame Project Learning (5) Transplantation of libjpeg-turbo
随机推荐
LVS负载均衡群集及部署LVS-NAT实验
Methods annotated with ‘@Async‘ must be overridable
【数据分析】基于MATLAB实现SVDD决策边界可视化
5. Software testing ----- automated testing
Conversational Technology!
[QNX Hypervisor 2.2用户手册]10 虚拟设备参考
WordPress博客问答小插件
【Arduino】重生之Arduino 学僧(3)----Arduino函数
Jenkins2.328+sonarqube7.9 实现代码自动化检测
二叉树的前序遍历、中序遍历、后序遍历和层序遍历
ClickHouse数据类型
大厂标配 | 百亿级并发系统设计 | 学完薪资框框涨
leetcode:151. 颠倒字符串中的单词
YYGH-BUG-06
leetcode:153. 寻找旋转排序数组中的最小值
能添加任意贴图超级复布局的初级智能文本提示器(超级版)
【TA-霜狼_may-《百人计划》】先行部分 手搓视差体积云
【Arduino】重生之Arduino 学僧(2)----Arduino语言
【Objective-C语言中的@property增强】
leetcode:162. 寻找峰值