|
本帖最后由 topdog 于 2021-1-24 15:27 编辑
设问串口接收十六进制的一串代码:00 00 00 00 00 00 FA 01,需要截取FA此段位置,即将00~FF转换成对应的十进制0~255,控制灯的亮度。
1,从串口读取单个的字符,把它们连接成字符串inputString。
2,Arduino在处理字符串有自己独特的语法,使用起来非常方便。譬如截取F,它在inputString字符串中第18位,至第19位截取,所以写成inputString.substring(18, 19)。第一个0的位置它的序列号是0呀!
3,十六进制FA,规范的写法是0xFA,对应的十进制值是250。十六进制的F表示15,A表示10,十六进制(HEX)转换十进制(DEC)公式:F*16^1+A*16^0=250 。
4,此程序中使用Aduino字符串的法言法语自定义函数int HexChangeDec(String ch),大家可以玩味一下。String虽然截取了一个字符但是在程序中依然是字符串类型(string),不是字符类型(char)。
[pre]const int LedPin = 9;
String inputString = "";
bool Status = false;
void setup()
{
Serial.begin(9600);
pinMode(LedPin, OUTPUT);
analogWrite(LedPin, 0);
inputString.reserve(200);
}
void loop()
{
if (Status)
{
//Serial.println(inputString);
String Ten = inputString.substring(18, 19);
String Unit = inputString.substring(19, 20);
int Val = HexChangeDec(Ten) * 16 + HexChangeDec(Unit);
//Serial.println(Val);
analogWrite(LedPin, Val);
inputString = "";
Serial.flush();
Status = false;
}
}
int HexChangeDec(String ch)
{
String Hex0 = "0123456789ABCDEF";
for (int i = 0; i < Hex0.length() + 1; i++)
{
String Hex1 = Hex0.substring(i, i + 1);
if (ch == Hex1)
{
return i;
}
}
}
void serialEvent()
{
if (Serial.available())
{
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n')
{
Status = true;
}
}
}[/pre]
5,举一反三,我们还可以使用字符串处理函数charAt(),截取字节类型,再结合ASCII编码的序列计算出十进制值。charAt()应用时字符在字符串中的实际位置截取。例如:00 00 00 00 00 00 FA 01里面,截取F, 即inputString.charAt(18)。
6,ASCII编码是由二进制表示的,譬如'0',二进制就是0011 0000,用十进制表示就是48。再如‘A’,二进制就是0100 0001,用十进制表示就是65。
7,0~9的ASCII编码减去48(字符0作为基准)一定小于10,字符编码和A字符编码之差就是十进制的值。另外A~F的ASCII编码减去48一定大于10,9到A还间隔了7个字符,所以减去7,才能求得对应的十进制值。
8,本例(ch - '0' > 10) ? ch - '0' - 7 : ch - '0' 是三元运算符,她是软件编程中的一个固定格式,语法是“条件表达式?表达式1:表达式2”。使用这个算法可以使调用数据时逐级筛选。条件表达式为真,输出为表达式1的值;条件表达式为假,输出为表达式2的值。
[pre]const int LedPin = 9;
String inputString = "";
bool Status = false;
void setup()
{
Serial.begin(9600);
pinMode(LedPin, OUTPUT);
analogWrite(LedPin, 0);
inputString.reserve(200);
}
void loop()
{
if (Status)
{
//Serial.println(inputString);
char Ten = inputString.charAt(18);
char Unit = inputString.charAt(19);
int Val = HexChangeDec(Ten) * 16 + HexChangeDec(Unit);
//Serial.println(Val);
analogWrite(LedPin, Val);
inputString = "";
Serial.flush();
Status = false;
}
}
int HexChangeDec(char ch)
{
return (ch - '0' > 10) ? ch - '0' - 7 : ch - '0';
}
void serialEvent()
{
if (Serial.available())
{
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n')
{
Status = true;
}
}
}[/pre]
9,打开串口监视器,请注意程序里面 inChar == '\n','\n'为换行符,所以要在右下角选择换行符,这样就可以直接在串口输入行键入编码实现控制了。
10,UNO支持analogWrite()功能的管脚是3、5、6、9、10、11,带有~符号标记。
|
|