我正在用SIM7000 4G调制解调器对ESP32进行编程,并且调制解调器库具有从调制解调器获取包含21个变量的CSV字符串并将其部分解析为变量的功能。原始作者只关心少量变量,因此传递了指针。
如果我想修改代码以使所有变量可用,似乎很难传递21个指针,特别是如果我一次只关心几个变量的话。这是结构的情况吗?使数据可用的最人性化方式是什么?
该功能将AT command发送到带有GPS芯片的蜂窝调制解调器(SIM7000)。接收到该命令后,芯片会内部解析来自GPS的NEMA数据,并返回CSV字符串以及所有相关数据。
class WorkerTests {
class Loop {
public Task innerLoop;
public void Run(CancellationToken token) {
this.innerLoop = Task.Run(LoopAsync, token); //wont enter in LoopAsync
}
private async Task LoopAsync() {
while (true) { //i want to reach here
Debug.WriteLine("in loop");
await Task.Delay(1000);
}
}
}
[TestCase]
public async Task TestLoop() {
CancellationTokenSource src = new CancellationTokenSource();
Loop loop = new Loop();
loop.Run(src.Token);
await loop.innerLoop;
}
}
完整代码:Library-see line 771 / Code calling library-line 134
我分叉了图书馆,让它也返回GPS路线信息,并想为什么不让所有返回的数据可用,但似乎不友好,必须传递21个指针或定义21个成员结构,然后传递他们的主要代码只关心纬度/经度,甚至只是速度。
我喜欢并与独立gps接收器一起使用的一个库是TinyGPS++。它返回数据作为对象的一部分,例如LoopAsync
。那是最好的方法吗?我一直在通过混搭不同的示例来通过Arduino学习C / C ++。
答案 0 :(得分:1)
是的。对于struct(针对Structure(s)的c / c ++关键字),这是一个很好的例子。
“ 结构(有时称为集合)是一个名称下相关变量的集合。与仅包含相同数据类型元素的数组相比,结构可能包含许多不同数据类型的变量。”-C如何编写Paul和Harvey Deitel编写的6.Ed。
就您而言,您必须返回大约21个不同的变量,对吗?因此,使用结构创建自定义数据类型时,可以说gpsData的成员是您要返回的21个变量,这使您能够编写一种函数,以紧凑的方式使用“ gpsData”返回数据。当然,您必须将gsm模块中的每个派生/解析的数据项分配给“ gpsData”的每个成员。
参考您的代码:
bool getGPS(float *lat, float *lon, float *speed=0, float *alt=0, float *course=0, int *vsat=0, int *usat=0) {
//String buffer = "";
bool fix = false;
sendAT(GF("+CGNSINF"));
if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
return false;
}
stream.readStringUntil(','); // mode [GNSS off=0, GNSS on=1]
if ( stream.readStringUntil(',').toInt() == 1 ) fix = true;
stream.readStringUntil(','); //utctime yyyyMMddhhmmss.sss
*lat = stream.readStringUntil(',').toFloat(); //lat ±dd.dddddd
*lon = stream.readStringUntil(',').toFloat(); //lon ±ddd.dddddd
if (alt != NULL) *alt = stream.readStringUntil(',').toFloat(); //altitude metere
if (speed != NULL) *speed = stream.readStringUntil(',').toFloat(); //speed Km/hour [0,999.99]
if (course != NULL) *course = stream.readStringUntil(',').toFloat(); //course over ground degrees [0,360.00]
stream.readStringUntil(',');//Fix mode [0,1,2]
stream.readStringUntil(',');//Reserved1
stream.readStringUntil(',');//HDOP [0,99.9]
stream.readStringUntil(',');//PDOP [0,99.9]
stream.readStringUntil(',');//VDOP [0,99.9]
stream.readStringUntil(',');//Reserved2
if (vsat != NULL) *vsat = stream.readStringUntil(',').toInt(); //viewed satelites
if (usat != NULL) *usat = stream.readStringUntil(',').toInt(); //used satelites
stream.readStringUntil(',');//GLONASS Sats used
stream.readStringUntil(',');//Reserved3
stream.readStringUntil(',');//C/N0 max (dBHz 0-55)
stream.readStringUntil(',');//HPA (meters [0,9999.9])
stream.readStringUntil(',');//VPA (meters [0,9999.9])
stream.readStringUntil('\n');
waitResponse();
return fix;
}
这些变量:float * lat,float * lon,float * speed = 0,float * alt = 0,float * course = 0,int * vsat = 0,int * usat = 0可以放入类似的结构中这个:
struct gpsData{
bool fix;
float lat;
float lon;
float speed;
float alt;
float course;
int vsat;
int usat;
....x_datatype y_variable;
};
其中x_datatype y_variable引用您可能要添加的其他成员变量。
您的getGPS功能现在将变成这样:
gpsData getGPS(){
gsmData temp;
temp.fix = false;
// required processing...
// ...
return temp;
}
当调用getGPS()时,如以下示例所示:
gpsData parsed_gps_data = getGPS();
您现在可以像这样获得您感兴趣的参数/成员/属性:
parsed_gps_data.fix;
parsed_gps_data.lat;
parsed_gps_data.lon;
我希望这种解释可以使一切变得清楚。