VX-3R APRS发射试验

VX-3R本身是不带APRS功能的,不过可能通过外加TNC实现APRS功能。
有大佬已经用Arduino实现了相应的发射功能:
https://github.com/handiko/Arduino-APRS
我要做的,就是简单修改一下代码,做一个转接板。
YEASU官方没有给出VX-3R的音频接口四节定义,估计是为了推销自家的CT-44,手册上只有这么一个图
在这里插入图片描述
在网上查了一圈,pinguide上有这么个图,然后提了一句“Pinouts for speaker and mic are reversed on the vx-3r”。但是经我实际验证,VX-3R的定义跟网站上是一样的,并没有reversed。
转接板原理图如下:
在这里插入图片描述
实物图如下:
在这里插入图片描述
值得注意的是,VX-3R的PTT是低电平发射。
完整的代码如下:

/**  Copyright (C) 2018 - Handiko Gesang - www.github.com/handiko*  *  This program is free software: you can redistribute it and/or modify*  it under the terms of the GNU General Public License as published by*  the Free Software Foundation, either version 3 of the License, or*  (at your option) any later version.*  *  This program is distributed in the hope that it will be useful,*  but WITHOUT ANY WARRANTY; without even the implied warranty of*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*  GNU General Public License for more details.*  *  You should have received a copy of the GNU General Public License*  along with this program.  If not, see <https://www.gnu.org/licenses/>.*/
#include <math.h>
#include <stdio.h>// Defines the Square Wave Output Pin
#define OUT_PIN 2#define _1200   1
#define _2400   0#define _FLAG       0x7e
#define _CTRL_ID    0x03
#define _PID        0xf0
#define _DT_EXP     ','
#define _DT_STATUS  '>'
#define _DT_POS     '!'#define _NORMAL     1
#define _BEACON     2#define _FIXPOS         1
#define _STATUS         2
#define _FIXPOS_STATUS  3#define _PTT      5bool nada = _2400;/** SQUARE WAVE SIGNAL GENERATION* * baud_adj lets you to adjust or fine tune overall baud rate* by simultaneously adjust the 1200 Hz and 2400 Hz tone,* so that both tone would scales synchronously.* adj_1200 determined the 1200 hz tone adjustment.* tc1200 is the half of the 1200 Hz signal periods.* *      -------------------------                           -------*     |                         |                         |*     |                         |                         |*     |                         |                         |* ----                           -------------------------* *     |<------ tc1200 --------->|<------ tc1200 --------->|*     * adj_2400 determined the 2400 hz tone adjustment.* tc2400 is the half of the 2400 Hz signal periods.* *      ------------              ------------              -------*     |            |            |            |            |*     |            |            |            |            |            *     |            |            |            |            |* ----              ------------              ------------* *     |<--tc2400-->|<--tc2400-->|<--tc2400-->|<--tc2400-->|*     */
const float baud_adj = 0.975;
const float adj_1200 = 1.0 * baud_adj;
const float adj_2400 = 1.0 * baud_adj;
unsigned int tc1200 = (unsigned int)(0.5 * adj_1200 * 1000000.0 / 1200.0);
unsigned int tc2400 = (unsigned int)(0.5 * adj_2400 * 1000000.0 / 2400.0);/** This strings will be used to generate AFSK signals, over and over again.*/
const char *mycall = "BG7GF";
char myssid = 7;const char *dest = "APRS";
const char *dest_beacon = "BEACON";const char *digi = "WIDE2";
char digissid = 1;const char *mystatus = "Hello World, This is a simple Arduino APRS Transmitter !";const char *lat = "28XX.09N";
const char *lon = "112XX.62E";
const char sym_ovl = 'H';
const char sym_tab = 'a';unsigned int tx_delay = 5000;
unsigned int str_len = 400;char bit_stuff = 0;
unsigned short crc=0xffff;/** */
void set_nada_1200(void);
void set_nada_2400(void);
void set_nada(bool nada);void send_char_NRZI(unsigned char in_byte, bool enBitStuff);
void send_string_len(const char *in_string, int len);void calc_crc(bool in_bit);
void send_crc(void);void send_packet(char packet_type, char dest_type);
void send_flag(unsigned char flag_len);
void send_header(char msg_type);
void send_payload(char type);void set_io(void);
void print_code_version(void);
void print_debug(char type, char dest_type);/** */
void set_nada_1200(void)
{digitalWrite(OUT_PIN, HIGH);delayMicroseconds(tc1200);digitalWrite(OUT_PIN, LOW);delayMicroseconds(tc1200);
}void set_nada_2400(void)
{digitalWrite(OUT_PIN, HIGH);delayMicroseconds(tc2400);digitalWrite(OUT_PIN, LOW);delayMicroseconds(tc2400);digitalWrite(OUT_PIN, HIGH);delayMicroseconds(tc2400);digitalWrite(OUT_PIN, LOW);delayMicroseconds(tc2400);
}void set_nada(bool nada)
{if(nada)set_nada_1200();elseset_nada_2400();
}/** This function will calculate CRC-16 CCITT for the FCS (Frame Check Sequence)* as required for the HDLC frame validity check.* * Using 0x1021 as polynomial generator. The CRC registers are initialized with* 0xFFFF*/
void calc_crc(bool in_bit)
{unsigned short xor_in;xor_in = crc ^ in_bit;crc >>= 1;if(xor_in & 0x01)crc ^= 0x8408;
}void send_crc(void)
{unsigned char crc_lo = crc ^ 0xff;unsigned char crc_hi = (crc >> 8) ^ 0xff;send_char_NRZI(crc_lo, HIGH);send_char_NRZI(crc_hi, HIGH);
}void send_header(char msg_type)
{char temp;/** APRS AX.25 Header * ........................................................* |   DEST   |  SOURCE  |   DIGI   | CTRL FLD |    PID   |* --------------------------------------------------------* |  7 bytes |  7 bytes |  7 bytes |   0x03   |   0xf0   |* --------------------------------------------------------* * DEST   : 6 byte "callsign" + 1 byte ssid* SOURCE : 6 byte your callsign + 1 byte ssid* DIGI   : 6 byte "digi callsign" + 1 byte ssid* * ALL DEST, SOURCE, & DIGI are left shifted 1 bit, ASCII format.* DIGI ssid is left shifted 1 bit + 1* * CTRL FLD is 0x03 and not shifted.* PID is 0xf0 and not shifted.*//********* DEST ***********/if(msg_type == _NORMAL){temp = strlen(dest);for(int j=0; j<temp; j++)send_char_NRZI(dest[j] << 1, HIGH);}else if(msg_type == _BEACON){temp = strlen(dest_beacon);for(int j=0; j<temp; j++)send_char_NRZI(dest_beacon[j] << 1, HIGH);}if(temp < 6){for(int j=0; j<(6 - temp); j++)send_char_NRZI(' ' << 1, HIGH);}send_char_NRZI('0' << 1, HIGH);/********* SOURCE *********/temp = strlen(mycall);for(int j=0; j<temp; j++)send_char_NRZI(mycall[j] << 1, HIGH);if(temp < 6){for(int j=0; j<(6 - temp); j++)send_char_NRZI(' ' << 1, HIGH);}send_char_NRZI((myssid + '0') << 1, HIGH);/********* DIGI ***********/temp = strlen(digi);for(int j=0; j<temp; j++)send_char_NRZI(digi[j] << 1, HIGH);if(temp < 6){for(int j=0; j<(6 - temp); j++)send_char_NRZI(' ' << 1, HIGH);}send_char_NRZI(((digissid + '0') << 1) + 1, HIGH);/***** CTRL FLD & PID *****/send_char_NRZI(_CTRL_ID, HIGH);send_char_NRZI(_PID, HIGH);
}void send_payload(char type)
{/** APRS AX.25 Payloads* * TYPE : POSITION* ........................................................* |DATA TYPE |    LAT   |SYMB. OVL.|    LON   |SYMB. TBL.|* --------------------------------------------------------* |  1 byte  |  8 bytes |  1 byte  |  9 bytes |  1 byte  |* --------------------------------------------------------* * DATA TYPE  : !* LAT        : ddmm.ssN or ddmm.ssS* LON        : dddmm.ssE or dddmm.ssW* * * TYPE : STATUS* ..................................* |DATA TYPE |    STATUS TEXT      |* ----------------------------------* |  1 byte  |       N bytes       |* ----------------------------------* * DATA TYPE  : >* STATUS TEXT: Free form text* * * TYPE : POSITION & STATUS* ..............................................................................* |DATA TYPE |    LAT   |SYMB. OVL.|    LON   |SYMB. TBL.|    STATUS TEXT      |* ------------------------------------------------------------------------------* |  1 byte  |  8 bytes |  1 byte  |  9 bytes |  1 byte  |       N bytes       |* ------------------------------------------------------------------------------* * DATA TYPE  : !* LAT        : ddmm.ssN or ddmm.ssS* LON        : dddmm.ssE or dddmm.ssW* STATUS TEXT: Free form text* * * All of the data are sent in the form of ASCII Text, not shifted.* */if(type == _FIXPOS){send_char_NRZI(_DT_POS, HIGH);send_string_len(lat, strlen(lat));send_char_NRZI(sym_ovl, HIGH);send_string_len(lon, strlen(lon));send_char_NRZI(sym_tab, HIGH);}else if(type == _STATUS){send_char_NRZI(_DT_STATUS, HIGH);send_string_len(mystatus, strlen(mystatus));}else if(type == _FIXPOS_STATUS){send_char_NRZI(_DT_POS, HIGH);send_string_len(lat, strlen(lat));send_char_NRZI(sym_ovl, HIGH);send_string_len(lon, strlen(lon));send_char_NRZI(sym_tab, HIGH);send_char_NRZI(' ', HIGH);send_string_len(mystatus, strlen(mystatus));}
}/** This function will send one byte input and convert it* into AFSK signal one bit at a time LSB first.* * The encode which used is NRZI (Non Return to Zero, Inverted)* bit 1 : transmitted as no change in tone* bit 0 : transmitted as change in tone*/
void send_char_NRZI(unsigned char in_byte, bool enBitStuff)
{bool bits;for(int i = 0; i < 8; i++){bits = in_byte & 0x01;calc_crc(bits);if(bits){set_nada(nada);bit_stuff++;if((enBitStuff) && (bit_stuff == 5)){nada ^= 1;set_nada(nada);bit_stuff = 0;}}else{nada ^= 1;set_nada(nada);bit_stuff = 0;}in_byte >>= 1;}
}void send_string_len(const char *in_string, int len)
{for(int j=0; j<len; j++)send_char_NRZI(in_string[j], HIGH);
}void send_flag(unsigned char flag_len)
{for(int j=0; j<flag_len; j++)send_char_NRZI(_FLAG, LOW); 
}/** In this preliminary test, a packet is consists of FLAG(s) and PAYLOAD(s).* Standard APRS FLAG is 0x7e character sent over and over again as a packet* delimiter. In this example, 100 flags is used the preamble and 3 flags as* the postamble.*/
void send_packet(char packet_type, char dest_type)
{print_debug(packet_type, dest_type);digitalWrite(LED_BUILTIN, 1);digitalWrite(_PTT, LOW);/** AX25 FRAME* * ........................................................* |  FLAG(s) |  HEADER  | PAYLOAD  | FCS(CRC) |  FLAG(s) |* --------------------------------------------------------* |  N bytes | 22 bytes |  N bytes | 2 bytes  |  N bytes |* --------------------------------------------------------* * FLAG(s)  : 0x7e* HEADER   : see header* PAYLOAD  : 1 byte data type + N byte info* FCS      : 2 bytes calculated from HEADER + PAYLOAD*/send_flag(100);crc = 0xffff;send_header(dest_type);send_payload(packet_type);send_crc();send_flag(3);digitalWrite(_PTT, HIGH);digitalWrite(LED_BUILTIN, 0);
}/** Function to randomized the value of a variable with defined low and hi limit value.* Used to create random AFSK pulse length.*/
void randomize(unsigned int &var, unsigned int low, unsigned int high)
{var = random(low, high);
}/** */
void set_io(void)
{pinMode(LED_BUILTIN, OUTPUT);pinMode(OUT_PIN, OUTPUT);pinMode(_PTT, OUTPUT);digitalWrite(_PTT, HIGH);Serial.begin(115200);
}void print_code_version(void)
{Serial.println(" ");Serial.print("Sketch:   ");   Serial.println(__FILE__);Serial.print("Uploaded: ");   Serial.println(__DATE__);Serial.println(" ");Serial.println("Random String Pulsed AFSK Generator - Started \n");
}void print_debug(char type, char dest_type)
{/** PROTOCOL DEBUG.* * Will outputs the transmitted data to the serial monitor* in the form of TNC2 string format.* * MYCALL-N>APRS,DIGIn-N:<PAYLOAD STRING> <CR><LF>*//****** MYCALL ********/Serial.print(mycall);Serial.print('-');Serial.print(myssid, DEC);Serial.print('>');/******** DEST ********/if(dest_type == _NORMAL){Serial.print(dest);}else if(dest_type == _BEACON){Serial.print(dest_beacon);}Serial.print(',');/******** DIGI ********/Serial.print(digi);Serial.print('-');Serial.print(digissid, DEC);Serial.print(':');/******* PAYLOAD ******/if(type == _FIXPOS){Serial.print(_DT_POS);Serial.print(lat);Serial.print(sym_ovl);Serial.print(lon);Serial.print(sym_tab);}else if(type == _STATUS){Serial.print(_DT_STATUS);Serial.print(mystatus);}else if(type == _FIXPOS_STATUS){Serial.print(_DT_POS);Serial.print(lat);Serial.print(sym_ovl);Serial.print(lon);Serial.print(sym_tab);Serial.print(' ');Serial.print(mystatus);}Serial.println(' ');
}/** */
void setup()
{set_io();print_code_version();
}void loop()
{send_packet(random(1,4), random(1,3));delay(tx_delay);randomize(tx_delay, 10, 5000);randomize(str_len, 10, 420);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/180622.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv5:按每个类别的不同置信度阈值输出预测框

YOLOv5&#xff1a;按每个类别的不同置信度阈值输出预测框 前言前提条件相关介绍YOLOv5&#xff1a;按每个类别的不同置信度阈值输出预测框预测修改detect.py输出结果 验证修改val.py输出结果 参考 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更…

走近Python爬虫(二):常见反爬虫机制的应对措施

文章目录 一、应对—异步加载1.一般措施2.Selenium 二、应对—登录验证1.使用Selenium模拟登录2.使用Cookies登录3.使用Session模拟表单登录 三、应对—验证码 本文是Python爬虫系列博客的第二篇&#xff0c;内容概览如下&#xff1a; 一、应对—异步加载 1.一般措施 AJAX技术…

在二维矩阵/数组中查找元素 Leetcode74, Leetcode240

这一类题型中二维数组的元素取值有序变化&#xff0c;因此可以用二分查找法。我们一起来看一下。 一、Leetcode 74 Leetcode 74. 搜索二维矩阵 这道题要在一个二维矩阵中查找元素。该二维矩阵有如下特点&#xff1a; 每行元素 从左到右 按非递减顺序排列。每行的第一个元素 …

【ArcGIS模型构建器】06:ArcGIS中DOM批量分幅教程

ArcGIS中利用模型构建器实现DOM批量分幅裁剪。 文章目录 1. 加载数据2. 批量分幅1. 加载数据 批量分幅通常是基于数字正射影像来实现。 数字正射影像(DOM.tif)CASS标准图幅(shp) 2. 批量分幅 单个图幅可以通过裁剪或者按掩膜提取工具来进行,批量分幅采用模型构建器进行。…

虹科案例 | AR内窥镜手术应用为手术节约45分钟?

相信医疗从业者都知道&#xff0c;在手术室中有非常多的医疗器械屏幕&#xff0c;特别是内窥镜手术室中医生依赖这些内窥镜画面来帮助病患进行手术。但手术室空间有限&#xff0c;屏幕缩放位置相对固定&#xff0c;在特殊场景下医生观看内窥镜画面时无法关注到病患的状态。这存…

Linux背景介绍与环境搭建

本章内容 认识 Linux, 了解 Linux 的相关背景学会如何使用云服务器掌握使用远程终端工具 xshell 登陆 Linux 服务器 Linux 背景介绍 发展史 本门课程学习Linux系统编程&#xff0c;你可能要问Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展…

MFC 窗体插入图片

1.制作BMP图像1.bmp 放到res文件夹下&#xff0c;资源视图界面导入res文件夹下的1.bmp 2.添加控件 控件类型修改为Bitmap 图像&#xff0c;选择IDB_BITMAP1 3.效果

MySQL---搜索引擎

MySQL的存储引擎是什么 MySQL当中数据用各种不同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制&#xff0c;索引技巧 锁定水平&#xff0c;以及最终提供的不同的功能和能力&#xff0c;这些就是我们说的存储引擎。 MySQL存储引擎的功能 1.MySQL将数据存储在文…

LabVIEW对多个同一类型控件进行操作

LabVIEW对多个同一类型控件进行操作 有时候LabVIEW要多多个同一类的控件进行操作&#xff0c;如对tab中某个page中所有String控件设为dissable。就可以用如下的方式。className是获取不同类型的控件。通过类型选择&#xff0c;可以选择所有的String控件&#xff0c;并可对特定…

双链表详解(初始化、插入、删除、遍历)(数据结构与算法)

1. 单链表与双链表的区别 单链表&#xff08;Singly Linked List&#xff09;和双链表&#xff08;Doubly Linked List&#xff09;是两种常见的链表数据结构&#xff0c;它们在节点之间的连接方式上有所区别。 单链表&#xff1a; 单链表的每个节点包含两个部分&#xff1a;数…

Synchronized与锁升级

一&#xff1a;java对象内存布局 对象在堆内存的存储布局可以划分为三个部分&#xff1a;对象头&#xff08;Header&#xff09;、实例数据&#xff08;Instance Data&#xff09; 和对齐填充 二&#xff1a;对象在堆内存中的存储布局 三&#xff1a;Sychronized的锁升级 S…

使用vscode实现远程开发,并通过内网穿透在公网环境下远程连接

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

中文大语言模型汇总

推荐一篇非常棒的github&#xff1a;Awesome-Chinese-LLM 另附语言模型排行榜&#xff1a;FastChat 里面总结了几乎所有目前主流的中文大语言模型。在此记录一下&#xff0c;方便以后慢慢学习。

Adobe After Effects 2024(Ae2024)在新版本中的升级有哪些?

After Effects 2024是Adobe公司推出的一款视频处理软件&#xff0c;它适用于从事设计和视频特技的机构&#xff0c;包括电视台、动画制作公司、个人后期制作工作室以及多媒体工作室。通过After Effects&#xff0c;用户可以高效且精确地创建无数种引人注目的动态图形和震撼人心…

串口代码整合2-如何接收数据?

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

基于SSM的搬家预约系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

阿里云安全恶意程序检测

阿里云安全恶意程序检测 赛题理解赛题介绍赛题说明数据说明评测指标 赛题分析数据特征解题思路 数据探索数据特征类型数据分布箱型图 变量取值分布缺失值异常值分析训练集的tid特征标签分布测试集数据探索同上 数据集联合分析file_id分析API分析 特征工程与基线模型构造特征与特…

List 接口常用实现类底层分析

一、集合 1.1 简介 集合主要分为两组&#xff08;单列集合、双列集合&#xff09;&#xff0c;Collection 接口有两个重要的子接口 List 和Set&#xff0c;它们的实现子类都是单列集合。Map 接口的实现子类是双列集合&#xff0c;存放的是 K-V 1.2 关系图 二、Collection 接口…

openLayers--绘制多边形、获取视图的中心点、获取当前地图等级、设置地图等级

openLayers绘制多边形、获取视图中心点 前言效果图1、导入LineString2、创建添加多边形3、定义多变形样式4、获取当前视图的中心点5、获取当前视图等级6、设置地图等级 前言 上一篇文章在vue项目中绘制了openlayers绘制了地图和标记点&#xff0c;本篇文章讲解openlayers绘制多…

【IDEA使用maven package时,出现依赖不存在以及无法从仓库获取本地依赖的问题】

Install Parent project C:\Users\lxh\.jdks\corretto-1.8.0_362\bin\java.exe -Dmaven.multiModuleProjectDirectoryD:\学习\projectFile\study\study_example_service "-Dmaven.homeD:\Program Files\JetBrains\IntelliJ IDEA2021\plugins\maven\lib\maven3" "…