AT 命令在程序中执行失败

AT Commands fail to Execute in a program

程序如下:

</p> <pre><code>#include <SoftwareSerial.h> SoftwareSerial gprsSerial(7, 8); byte sensorInterrupt = 0; // 0 = digital pin 2 byte sensorPin = 2; // The hall-effect flow sensor outputs approximately 4.5 pulses per second per // litre/minute of flow. float calibrationFactor = 4.5; volatile byte pulseCount; float flowRate; unsigned int flowMilliLitres; unsigned long totalMilliLitres; unsigned long oldTime; void setup() { gprsSerial.begin(19200); Serial.begin(19200); pinMode(sensorPin, INPUT); digitalWrite(sensorPin, HIGH); pulseCount = 0; flowRate = 0.0; flowMilliLitres = 0; totalMilliLitres = 0; oldTime = 0; // The Hall-effect sensor is connected to pin 2 which uses interrupt 0. // Configured to trigger on a FALLING state change (transition from HIGH // state to LOW state) attachInterrupt(sensorInterrupt, pulseCounter, FALLING); Serial.println("Config SIM900..."); delay(2000); Serial.println("Done!..."); gprsSerial.flush(); Serial.flush(); // attach or detach from GPRS service gprsSerial.println("AT+CGATT?"); delay(100); toSerial(); // bearer settings gprsSerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); delay(2000); toSerial(); // bearer settings gprsSerial.println("AT+SAPBR=3,1,\"APN\",\"uninor\""); delay(3000); toSerial(); // bearer settings gprsSerial.println("AT+SAPBR=1,1"); delay(2000); toSerial(); // bearer settings gprsSerial.println("AT+SAPBR=2,1"); delay(3000); toSerial(); gprsSerial.println("AT+HTTPINIT"); delay(2000); toSerial(); } void loop() { if ((millis() - oldTime) > 1000) // Only process counters once per second { // Disable the interrupt while calculating flow rate and sending the value to // the host detachInterrupt(sensorInterrupt); // Because this loop may not complete in exactly 1 second intervals we calculate // the number of milliseconds that have passed since the last execution and use // that to scale the output. We also apply the calibrationFactor to scale the output // based on the number of pulses per second per units of measure (litres/minute in // this case) coming from the sensor. flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor; // Note the time this processing pass was executed. Note that because we've // disabled interrupts the millis() function won't actually be incrementing right // at this point, but it will still return the value it was set to just before // interrupts went away. oldTime = millis(); // Divide the flow rate in litres/minute by 60 to determine how many litres have // passed through the sensor in this 1 second interval, then multiply by 1000 to // convert to millilitres. flowMilliLitres = (flowRate / 60) * 1000; // Add the millilitres passed in this second to the cumulative total totalMilliLitres += flowMilliLitres; unsigned int frac; // Print the flow rate for this second in litres / minute Serial.print("Flow rate: "); Serial.print(int(flowRate)); // Print the integer part of the variable Serial.print("L/min"); Serial.print("\t"); // Print tab space // Print the cumulative total of litres flowed since starting Serial.print("Output Liquid Quantity: "); Serial.print(totalMilliLitres); Serial.println("mL"); Serial.print("\t"); // Print tab space Serial.print(totalMilliLitres / 1000); Serial.print("L"); // Reset the pulse counter so we can start incrementing again pulseCount = 0; // Enable the interrupt again now that we've finished sending output attachInterrupt(sensorInterrupt, pulseCounter, FALLING); } // set http param value gprsSerial.println("AT+HTTPPARA=\"URL\",\"http://210.16.100.71:8090/watersupply/webservices/test.php?flowratereading=1500\""); delay(2000); toSerial(); // set http action type 0 = GET, 1 = POST, 2 = HEAD gprsSerial.println("AT+HTTPACTION=0"); delay(6000); toSerial(); // read server response gprsSerial.println("AT+HTTPREAD"); delay(1000); toSerial(); gprsSerial.println(""); delay(10000); } void toSerial() { while (gprsSerial.available() != 0) { Serial.write(gprsSerial.read()); } } void pulseCounter() { // Increment the pulse counter pulseCount++; }

上述程序中的AT命令没有立即执行并显示错误: 串行监视器上的结果如下所示:

这些单独执行的命令就像 Charm 一样工作。

这里的主要问题是,当您调用 delay 而不是 读取和解析 从调制解调器返回的响应时,任何事情都不会可靠地或根本不会工作。您必须阅读并解析返回的回复。

尝试使用 delay 就像踢挡路的狗以让它们移动一样有用。是的,它有时可能确实有效,但在某些时候你会后悔采用这种方法......

有关如何正确执行此操作的一些指南,请参阅 this answer. I suspect that you possibly are aborting some of the commands, see the first part of this answer 以了解更多详细信息。

旁注:您应该始终在尽可能短的时间内禁用中断,因此您绝对应该将所有 Serial.print 移动到 attachInterrupt 之后。