如何从C / C ++中的函数返回几个可选变量?

时间:2019-05-03 13:50:27

标签: arduino arduino-c++

我正在用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 ++。

1 个答案:

答案 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;

我希望这种解释可以使一切变得清楚。