Запись данных с Serial d EEPROM

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Кусок кода

void loop() 
{
  if (Serial.available() > 0) {
    serial = Serial.read();
      if (serial==42) { 
       Serial.print (ip1);
       Serial.print (".");
       Serial.print (ip2);
       Serial.print (".");
       Serial.print (ip3);
       Serial.print (".");
       Serial.print (ip4);
       Serial.println ();
       Serial.println ("Enter the new IP: 1_2_3.4_5_6.7_8_9.10_11_12");
       
          Serial.println ("1: ");
          do {
          ips1 = Serial.read();}
          while (ips1 >0);
          Serial.println ("2: ");
          do {
          ips2 = Serial.read();}
          while (ips2 >0);
          Serial.println ("3: ");
           do {
          ips3 = Serial.read();}
          while (ips3 >0);
          Serial.println ("4: ");
           do {
          ips4 = Serial.read();}
          while (ips4 >0);
          Serial.println ("5: ");
           do {
          ips5 = Serial.read();}
          while (ips5 >0);
          Serial.println ("6: ");
           do {
          ips6 = Serial.read();}
          while (ips6 >0);
          Serial.println ("7: ");
           do {
          ips7 = Serial.read();}
          while (ips7 >0);
          Serial.println ("8: ");
           do {
          ips8 = Serial.read();}
          while (ips8 >0);
          Serial.println ("9: ");
           do {
          ips9 = Serial.read();}
          while (ips9 >0);
          Serial.println ("10: ");
           do {
          ips10 = Serial.read();}
          while (ips10 >0);
          Serial.println ("11: ");
           do {
          ips11 = Serial.read();}
          while (ips11 >0);
          Serial.println ("12: ");
           do {
          ips12 = Serial.read();}
          while (ips1 >0);
          
     ipc1= (ips1-48)*100+(ips2-48)*10+ips3-48;
     EEPROM.write (ipc1, 0); 
     ipc2= (ips4-48)*100+(ips5-48)*10+ips6-48;
     EEPROM.write (ipc2, 1);
     ipc3= (ips7-48)*100+(ips8-48)*10+ips9-48;
     EEPROM.write (ipc3, 2);
     ipc4= (ips10-48)*100+(ips11-48)*10+ips12-48;
     EEPROM.write (ipc4, 3); 
     Serial.println ("New IP: ");
       Serial.print (ipc1);
       Serial.print (".");
       Serial.print (ipc2);
       Serial.print (".");
       Serial.print (ipc3);
       Serial.print (".");
       Serial.print (ipc4);
           
         
      
  }
       


  }

Дело собственно в функции ввода. Необходимо ожидание дуиной ввода какого либо числа. Но ардуинка не ждет. ткните плз носом где ошибка?

step962
Offline
Зарегистрирован: 23.05.2011

1. Посмотрите на строки 61-63. Возможно и в других местах есть такие очепятки.

2. Может быть стоит попробовать обнулить все ваши ips1...ips12, а потом в каждом из дюжины цикликов заменить условия выхода с while(ipsXX>0); на while(ipsXX==0);?

3. По каким соображениям вы отказались от использования массивов? 48 строк (16...63) вполне можно было бы сократить до четырех-пяти.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

step962 пишет:

1. Посмотрите на строки 61-63. Возможно и в других местах есть такие очепятки.

2. Может быть стоит попробовать обнулить все ваши ips1...ips12, а потом в каждом из дюжины цикликов заменить условия выхода с while(ipsXX>0); на while(ipsXX==0);?

3. По каким соображениям вы отказались от использования массивов? 48 строк (16...63) вполне можно было бы сократить до четырех-пяти.

 

1. исправил, спасибо.

2. обнуление есть в водной части программы

int ips1=0, ips2=0, ips3=0, ips4=0, ips5=0, ips6=0, ips7=0, ips8=0, ips9=0, ips10=0, ips11=0, ips12=0;

Исправил на while(ipsXX==0); толку нет.

3.  думал, но  что то пока не получилось....

ales2k
Offline
Зарегистрирован: 25.02.2013

Не ждет потому, что в буфере порта уже есть данные. Нужно очищать буфер, например так

void clearserial()
{
while(Serial.available()) 
   {
   delay(2);
   Serial.read();
   }
}

Затем читать например так

(не совсем оптимальный код, но работает) выдает byte, длинной numl, ждет ввода время wait

byte getserialbyte(long wait,byte numl)
{
  byte out=0;
  String str=String(2);
  char command;
  long int dela;
  byte k=1;
  dela=millis();
  byte in=0;
  do 
  {
    if (Serial.available()) 
    {
      command = Serial.read();
      if (command!=char(13)&&command!=char(10))
      {
        str.setCharAt(0,command);
        out=out*k+byte(str.toInt());
        k=k*10;
        in++;
      }
    }
    delay(10);
  }
  while ((millis()-dela<=wait)&&(in!=numl));
  return out;
}

 

Есть аналогичная встроенная функция, но у меня с ней постоянно глюки...

 

leshak
Offline
Зарегистрирован: 29.09.2011

>обнуление есть в водной части программы

Во первых - нужно было это давать сразу. Это тоже важно. Может вы  с типом ошиблись (кстати зачем тут int, почему не byte?). Во вторых - если вы дали "обрезанный кусок" - значит у себя никто не сможет проверить-запустить (то есть - вы снизили шансы на ответ).

Так же, "в водной части" - это значит один раз выполнится. При запуске. Значит скетч ваш, сможет один раз только считать все верно (что не есть здорово).

Но,IMHO, тут подход совсем не верный. Код сильно дублирован/раздут. А значит  где-то очепятатся/ошибился - легче, а найти - труднее.

Что, похоже вы и сделали в строке 63. Там не ips12 предполагалось?

Как только возникает желание объявить кучу переменных типа ips1,ips2,ips3..... это явный кандидат на использование массив (array)

Вот что-то такое можно сделать

byte ips[12];

тогда

можно писать что-то типа:

for(byte i=0;i<12;i++){
         Serial.print(i+1);Serial.println(": ");
         while(!Serial.avaliable()); // ждем следующего символа
         ips[i] = Serial.read();
}

В третьих... а зачем вообще столько ips?  если IP-шник это по определению четыре байта? А есть еще Arduino - ParseInt

То есть, что-то типа

byte ip[4];
...

for(int i=0;i<4;i++){
    ip[i]=Serial.parseInt();
}

// тут можете добавить проверку на правильность  введенного  ip-шник на правильность, выводим его пользователю и т.п.

//сохраняем в EEPROM
for(int i=0;i<4;i++){
  EEPROM.write(i,ip[i]);
}

Ну, что-бы это работало, без "секундных пауз" нужно что-бы в терминал мониторе Line Ending был выставлен передавать конец строки (что-бы по нажатию Enter отдавало символ "перевод строки").

P.S. И перечитайте еще раз внимательней EEPROM.write() | Аппаратная платформа Arduino  . При записи, адресс куда будет сохранено значение - это первый параметр, а не второй.

maksim
Offline
Зарегистрирован: 12.02.2012

Выше вам дали направление, вот рабочий пример на всякий:

#include <EEPROM.h>

void setup() 
{
  Serial.begin(9600);
  Serial.setTimeout(100); // что бы не ждать 1 секунду после ввода
}

void loop() 
{
  if(Serial.available())
  { 
    byte ip[4] = {0, 0, 0, 0};
    for(byte i = 0; i < 4; i++)
    {
      ip[i] = Serial.parseInt();
      EEPROM.write(i, ip[i]);
    }
    
    // для проверки читаем IP из ЕЕПРОМ и выводим в сериал
    for(byte i = 0; i < 4; i++)
    {
      ip[i] = EEPROM.read(i);
      Serial.print(ip[i]);
      if(i < 3) Serial.print('.');
      else Serial.println();
    }
  }
}

 

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Всем спасибо! 

Буду грызть.