Добрый день. Есть плата Arduino Leonardo ETH. Делаю небольшой скетч для посылки определенных данных на веб-сервер. Должно работать примерно так: 1) при старте в процедуры setup() читаю файл с карты памяти и устанавливаю глобальные переменные (ip адрес модуля arduino, mac адрес, ip адрес сервера и порт сервера). 2) в основной процедуре цикла loop() по задержкам отправляю запрос на веб-сервер. Проблема в том, что если определить переменную, например, ip адрес сервера (_serverip) в setup(), то в loop() она уже имеет не то значение, которое было установлено в setup(). Вывод в терминал, когда переменная _serverip определяется каждый раз в процедуре httpRequest(): Код (Text): server=192.168.200.33 id=VGL3Et ip=192.168.200.177 mac=90:A2:DA:10:0:E8 My IP address:192168200177 Starting ... Server IP address:19216820033 Вывод в терминал, когда переменная _serverip определяется один раз в процедуре setup(): Код (Text): server=192.168.200.33 id=VGL3Et ip=192.168.200.177 mac=90:A2:DA:10:0:E8 My IP address:192168200177 Starting ... Server IP address:1686140 Почему так может происходить ? Ведь переменная localip вполне нормально присваивается и не изменяется. Судя по сообщению компилятора при записи проекта в устройство размера ОЗУ достаточно для работы (занято около 60 %). Заранее благодарен за ответы. Код скетча: Код (Text): #include <SPI.h> #include <Ethernet2.h> #include <SD.h> byte mac[] = { 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 //fake MAC }; // initialize the library instance: EthernetClient client; String ip = "192.168.200.188"; String server = "192.168.200.44"; byte localip[] = {}; byte _serverip[] = {}; String DeviceId = "NoId"; String _Date = "12.09.2015"; String _Time = "08:23:50"; String _Delimetr = "%20"; //переменные портов int selectEthernet = 10; // выбор ведомого на шилде - Ethernet int selectSd = 4; // выбор ведомого на шилде - SD // включим Ethernet #define SWITCH_TO_ETH digitalWrite(selectSd,HIGH); digitalWrite(selectEthernet,LOW); // включим SD #define SWITCH_TO_SD digitalWrite(selectEthernet,HIGH); digitalWrite(selectSd,LOW); // выключим и SD и Ethernet #define ALL_OFF digitalWrite(selectEthernet,HIGH); digitalWrite(selectSd,HIGH); void setup() { // start serial port: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } //uncomment for write config /* writeconfig(); return; */ // give the ethernet module time to boot up: delay(1000); // Задаем режим работы портов pinMode(selectEthernet, OUTPUT); pinMode(selectSd, OUTPUT); readconfig(); //IPAddress serverip(strtoint(SplitString(server, '.', 0)), strtoint(SplitString(server, '.', 1)), strtoint(SplitString(server, '.', 2)), strtoint(SplitString(server, '.', 3))); //byte localip[] = { strtoint(SplitString(ip, '.', 0)), strtoint(SplitString(ip, '.', 1)), strtoint(SplitString(ip, '.', 2)), strtoint(SplitString(ip, '.', 3)) }; byte localip[] = { SplitString(ip, '.', 0).toInt(), SplitString(ip, '.', 1).toInt(), SplitString(ip, '.', 2).toInt(), SplitString(ip, '.', 3).toInt() }; //если раскомментировать здесь, то в loop() массив адреса будет неверный //byte _serverip[] = { SplitString(server, '.', 0).toInt(), SplitString(server, '.', 1).toInt(), SplitString(server, '.', 2).toInt(), SplitString(server, '.', 3).toInt() }; Serial.print("My IP address:"); Serial.print(localip[0]); Serial.print(localip[1]); Serial.print(localip[2]); Serial.println(localip[3]); Ethernet.begin(mac, localip); Serial.println("Starting ..."); } void loop() { delay(1000); httpRequest(_Date + _Delimetr + _Time, String(millis())); while (client.available()) { char c = client.read(); Serial.write(c); } client.stop(); } void httpRequest(String DateTime, String IdCard) { //приходится вызывать здесь каждый раз, ибо если вызвать из setup() переменная здесь уже неверная ( byte _serverip[] = { SplitString(server, '.', 0).toInt(), SplitString(server, '.', 1).toInt(), SplitString(server, '.', 2).toInt(), SplitString(server, '.', 3).toInt() }; Serial.print("Server IP address:"); Serial.print(_serverip[0]); Serial.print(_serverip[1]); Serial.print(_serverip[2]); Serial.println(_serverip[3]); if (client.connect(_serverip, 8080)) { Serial.println("connecting..."); // send the HTTP GET request: client.println("GET /resort/hs/MonitoringVisits/put_data?Date=" + DateTime + "&IdDevice=" + DeviceId + "&IdCard=" + IdCard + " HTTP/1.1"); client.println("Host: " + server); //client.println("User-Agent: arduino"); client.println("Connection: close"); client.println(); } else { Serial.println("connection failed"); } delay(5000); } String SplitString(String data, char separator, int index) { int found = 0; int strIndex[] = {0, -1}; int maxIndex = data.length() - 1; for (int i = 0; i <= maxIndex && found <= index; i++) { if (data.charAt(i) == separator || i == maxIndex) { found++; strIndex[0] = strIndex[1] + 1; strIndex[1] = (i == maxIndex) ? i + 1 : i; } } return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; } void writeconfig() { SWITCH_TO_SD; Serial.print("Init SD card..."); if (!SD.begin(selectSd)) { Serial.println("init failed!"); return; } Serial.println("init done."); if (SD.exists("config.txt")) { SD.remove("config.txt"); } File ConfigFile; ConfigFile = SD.open("config.txt", FILE_WRITE); if (ConfigFile) { ConfigFile.println("192.168.200.177"); ConfigFile.println("90A2DA1000E8"); ConfigFile.println("VGL3Et"); ConfigFile.println("192.168.200.33"); ConfigFile.println("8080"); ConfigFile.close(); } Serial.println("Testing"); Serial.print(mac[0], HEX); Serial.print(mac[1], HEX); Serial.print(mac[2], HEX); Serial.print(mac[3], HEX); Serial.print(mac[4], HEX); Serial.println(mac[5], HEX); String TempString = "90A2DA1000E8"; Serial.println(convert2hex(TempString.c_str(), mac)); //test MAC Serial.print(mac[0], HEX); Serial.print(mac[1], HEX); Serial.print(mac[2], HEX); Serial.print(mac[3], HEX); Serial.print(mac[4], HEX); Serial.println(mac[5], HEX); SWITCH_TO_ETH; } void readconfig() { SWITCH_TO_SD; if (!SD.begin(selectSd)) { Serial.println("init SD card failed!"); return; } if (SD.exists("config.txt")) { File ConfigFile; ConfigFile = SD.open("config.txt"); if (ConfigFile) { String TempString; int NumberOfString = 0; while (ConfigFile.available()) { char TempBuff = ConfigFile.read(); if (TempBuff == '\n') { NumberOfString++; if (NumberOfString == 1) { //IP адрес устройства ip = TempString; } else if (NumberOfString == 2) { //MAC адрес convert2hex(TempString.c_str(), mac); } else if (NumberOfString == 3) { //ID устройства DeviceId = TempString; } else if (NumberOfString == 4) { //IP адрес сервера server = TempString; } else if (NumberOfString == 5) { //порт сервера //serverport = TempString.toInt(); //это устанавливаем сразу ... } TempString = ""; } else if (TempBuff != '\r') { TempString += TempBuff; } } ConfigFile.close(); Serial.println("server=" + server); Serial.println("id=" + DeviceId); Serial.println("ip=" + ip); Serial.print("mac="); Serial.print(mac[0], HEX); Serial.print(":"); Serial.print(mac[1], HEX); Serial.print(":"); Serial.print(mac[2], HEX); Serial.print(":"); Serial.print(mac[3], HEX); Serial.print(":"); Serial.print(mac[4], HEX); Serial.print(":"); Serial.println(mac[5], HEX); } } else { Serial.println("config not found"); } SWITCH_TO_ETH; } typedef struct { char a; char b; } Btype; int convert2hex(const char *str, unsigned char *byte) // первый параметр указывает на массив символов, второй байт, возвращает колл-во байт { Btype *chp; chp = (Btype*)str; int i = 0; unsigned char c1, b1; while (chp[i].a) { c1 = (chp[i].a >= 65) ? 55 : 48; b1 = (chp[i].a - c1) << 4; c1 = (chp[i].b >= 65) ? 55 : 48; byte[i] = b1 | (chp[i].b - c1); i++; } return i; }
Каждая переменная живет только внутри своей области видимости, ограниченной блоком кода { ... }. Если вы определяете внутри блока переменную с таким же именем, как и снаружи, то наружная переменная становится недоступна, пока вы не покинете этот блок кода. Либо работайте с глобальными переменными, либо объявляйте локальные с другими именами и потом копируйте содержимое.
Небольшое дополнение: глобальные переменные объявляем следующим образом Код (Text): byte localip[] = {0,0,0,0}; byte _serverip[] = {0,0,0,0}; потом в 'setup' задаем значения Код (Text): localip[0] = SplitString(ip, '.', 0).toInt(); localip[1] = SplitString(ip, '.', 1).toInt(); localip[2] = SplitString(ip, '.', 2).toInt(); localip[3] = SplitString(ip, '.', 3).toInt(); _serverip[0] = SplitString(server, '.', 0).toInt(); _serverip[1] = SplitString(server, '.', 1).toInt(); _serverip[2] = SplitString(server, '.', 2).toInt(); _serverip[3] = SplitString(server, '.', 3).toInt(); В Вашем случае, как отметил Unixon, в 'setup' создаются локальные переменные 'localip' и '_serverip', аналогичные глобальным. И этим локальным переменным задаются значения, которые после выхода из функции 'loop' теряются.