如何逐个获取微控制器数据并减少字节数? [英] How Can I Get Microcontroller Data And Cut Bytes One By One ?

查看:55
本文介绍了如何逐个获取微控制器数据并减少字节数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好!

这是我的简短avr源代码:



  int  main( void 
{
sei(); // 启用全局中断
USART_Init(MYUBRR);
DDRB | =(0 <<< PINB0)|(1<< PINB1);
Init_mpu6050( 0 0 0 2000 16 ,off, 0 < /跨度>);
ACCEL_Sensitivity_set( 16 );
GYRO_Sensitivity_set( 2000 );
char buff [ 500 ]; // 重要:注意缓冲区的大小并确保其足够。
stdout =& ; mystdout;
while 1 ){
ACCEL_in_radian();
sprintf(buff, <%6.3f>,<%6.3f>,<% 6.3F>中,ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT);
put(buff);
}
}
}





使用此代码我可以获得3中的加速计浮点数据轴并将它们转换为字符串并保存为buff [0,1,...]



我的问题是如何发送此字符串Burst然后我切c#中的数据一个接一个?

我在MSDN上学习关于getbytes方法的一些东西,但它对我没有帮助!

i认为我必须逐个发送这样的字节:

  while  1 ){
ACCEL_in_radian();
sprintf(buff, <%6.3f>,<%6.3f>,<% 6.3F>中,ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT);
for int x = 0; x< 8; x ++){
printf( %c,buff [x]);
}



}

这是发送它们的标准方式吗?

它仅适用于其他1轴我必须再次循环2 ... ...

然后用一个符号<我收到字节和>停止接收! : - ?

有没有办法以ASCII格式发送数据?我如何在c#中逐个接收和分离轴数据?

thx很多。

解决方案

你应该决定一种适合您的格式。

您的第一选择是在二进制 ASCII 协议之间做出决定。

两者各有利弊,但简单地说就是



  • ASCII更易读,更容易调试,如果你想挂钩你的话更好设备使用HyperTerminal。

    但是为基于文本的协议创建解析器要困难一些。
  • 二进制协议更紧凑,如果你需要更好传输大型BLOB,如图像,更容易解析。

    它需要一个定义明确的规范,对于小数据传输,开销可以很大程度地与数据相关联。





在您的情况下,您似乎只接收设备中的数据且数据是数字的,我会选择ASCII协议。



这是基于您的数据构建的示例。如果我理解正确,你有三个轴,每个轴有三个值。



Axis start [(左方括号) 由于HTML格式化,我使用了这个字符。
Axis end ](右方括号) )
值分隔符 ,(逗号)
行结束字符 \ n(LineFeed) 这是SerialPort中的NewLine属性的默认值






 [10.333,11.444,12.555] [10.333,11.444 ,12.555] [10.333,11.444,12.555] \ n 





发送数据:

 ACCEL_in_radian(); 
printf( [%6.3f,%6.3f,%6.3f], ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT); // 第一轴
printf( [%6.3f,%6.3f,%6.3f],ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT); // 第二轴
printf( [%6.3f,%6.3f,%6.3f],ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT); // 第三轴
printf(' \ n');



不确定微控制器的工作原理。你可以打印整个字符串吗?





在c#方面,您现在可以使用ReadLine方法将所有数据合并到一个chunk。



要解释收到的字符串,你可以使用这个正则表达式。

正则表达式protocolExpression =  new 正则表达式( @  \ [(?< X> \d + \.\d +),(小于; Y> \d + \.\d +),(小于 -  Z> \d + \.\d +)\] ); < /   z  >  < /   y  >  < /   x  >  





  //  在主线程上设置此变量 
bool stopReading = false ;

// 在子线程中执行此部分
< span class =code-keyword> string strRecieve = ;
double x = 0 0 ;
double y = 0 0 ;
double z = 0 0 ;

while (!stopReading)
{
strRecieve = serialPort1.ReadLine();

MatchCollection mc = protocolExpression.Matches(strRecieve);
foreach (匹配m in mc)
{
// 逐个获取每个轴的数据
x = double .Parse(m.Groups [ x]。捕获[ 0 ]值);
y = double .Parse(m.Groups [ y]。捕获[ 0 ]。值);
z = double .Parse(m.Groups [ z]。捕获[ 0 ]。值);

// 向用户显示数据
}
}


使用C#获取数据很简单:只需设置一个SerialPort类实例,并处理DataRecieved事件。在那里,你可以逐字节或作为一组获取数据,并按照你的意愿去做。

或者,设置一个后台工作线程来从一个字节读取数据SerialPort使用ReadByte命令 - 它将锁定线程,直到一个字节可用。你可以用那里的数据做你喜欢的事。





thx你的回复!我知道如何使用serialport,我可以接收数据!我的问题是我如何分离任何轴的数据?





如果你只是把它组装成一个字符串作为一个完整的消息(你需要做的是确保你有整个消息,而不仅仅是一个片段)你可以通过一个正则表达式将它拉出你的位需要。

<(?< X> \d +(\。\ d +)?)>,<(?< Y> \ + +(\。\ d +)?)>,<(?< Z> \d +(\。\ d)?)> 

应该这样做。


hello guys!
this is my brief avr source code :

int main(void)
{
    sei();//Enable global interrupt
    USART_Init(MYUBRR );
    DDRB |=(0<<PINB0)|(1<<PINB1);
    Init_mpu6050(0,0,0,2000,16,off,0);
    ACCEL_Sensitivity_set(16);
    GYRO_Sensitivity_set(2000);
    char buff[500]; //important : attention to the size of buffer and sure its enough.
    stdout = &mystdout;
    while(1){
        ACCEL_in_radian();
        sprintf(buff,"<%6.3f>,<%6.3f>,<%6.3f>",ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT);
puts(buff);
    }
    }
}



with this code i can get the accelerometer float data in 3 axis and convert them to string and save to buff[0,1,...]

and my question is how can i send this string Burst then i cut any data one by one in c# ?
i study somthing about getbytes method in MSDN but it doesnt help me about this !
i think i must send bytes one by one somthing like this :

while(1){
    ACCEL_in_radian();
    sprintf(buff,"<%6.3f>,<%6.3f>,<%6.3f>",ACCEL_XOUT,ACCEL_YOUT,ACCEL_ZOUT);
    for (int x=0;x<8;x++){
    printf("%c",buff[x]);
}


}
is this the standard way to send them ?
its only for 1 axis for others i must make 2 for loop again ... !
then with one sign like "<" i receive bytes and with ">" stop receiving ! :-?
is there any way to send data In ASCII ? How can i receive and separate the axis data singly and one by one in c#?
thx a lot.

解决方案

You should decide on a format that works for you.
The first choice you have is to decide between a binary or ASCII protocol.
Both have their pros and cons, but simply put

  • ASCII is more readable, easier to debug and good if you want to hook your device up with HyperTerminal.
    It is a bit more difficult to create a parser for a text based protocol, though.
  • A binary protocol is more compact, good if you need to transfer large BLOBs, such as images, and easier to parse.
    It requires a well defined spec and for small data transfers the overhead can be large comapred to the data.


In your case where you seem to only receive data from your device and the data is numeric, I would go for an ASCII protocol.

This is an example built on your data. If I understand correctly you have three axis with three values each.

Axis start[ (left square bracket)I used this character due to HTML formatting.
Axis end] (right square bracket)
Value separator, (comma)
End of line char\n (LineFeed)This is the default value for the NewLine property in SerialPort



[10.333,11.444,12.555][10.333,11.444,12.555][10.333,11.444,12.555]\n



Sending data:

ACCEL_in_radian();
printf("[%6.3f,%6.3f,%6.3f]", ACCEL_XOUT, ACCEL_YOUT, ACCEL_ZOUT); // First axis
printf("[%6.3f,%6.3f,%6.3f]", ACCEL_XOUT, ACCEL_YOUT, ACCEL_ZOUT); // Second axis
printf("[%6.3f,%6.3f,%6.3f]", ACCEL_XOUT, ACCEL_YOUT, ACCEL_ZOUT); // Third axis
printf('\n');


Not sure how your micro controller works. Can you print a whole string?


On the c# side you can now use the method ReadLine in order to get all data in one chunk.

For interpreting your received string you can can use this regular expression.

Regex protocolExpression = new Regex(@"\[(?<x>\d+\.\d+),(?<y>\d+\.\d+),(?<z>\d+\.\d+)\]");</z></y></x>



// Set this variable on the main thread
bool stopReading = false;

// Do this part inside a child thread
string strRecieve = "";
double x = 0.0;
double y = 0.0;
double z = 0.0;

while (!stopReading)
{
    strRecieve = serialPort1.ReadLine();
    
    MatchCollection mc = protocolExpression.Matches(strRecieve);
    foreach (Match m in mc)
    {
        // Get data for each axis one by one
        x = double.Parse(m.Groups["x"].Captures[0].Value);
        y = double.Parse(m.Groups["y"].Captures[0].Value);
        z = double.Parse(m.Groups["z"].Captures[0].Value);

        // Present data to the user
    }
}


Getting the data in C# is simple: just set up a SerialPort class instance, and handle the DataRecieved event. In that, you can fetch data byte-by-byte or as a group, and do with it what you will.
Alternatively, set up a background worker thread to read data byte-by-byte from the SerialPort by using the ReadByte command - which will lock the thread until a byte is available. You can do what you like with the data from there on.


"thx for your reply ! i know how to work with serialport and i can receive data ! my problem is how can i separate data for any axis ?"


If you just assemble it into a string as a complete message (which you would need to do to make sure you have the whole message and not just a fragment) you can just pass it through a regex which will "pull out" the bits you need.

<(?<X>\d+(\.\d+)?)>,<(?<Y>\d+(\.\d+)?)>,<(?<Z>\d+(\.\d)?)>

Should do it.


这篇关于如何逐个获取微控制器数据并减少字节数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆