Прочитать COM порт в массив

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

С компьютера по COM отправляется текстовый файл. На листинге он выглядит так (в скобках пояснения):

Наим. блока 1   (16 символов фиксированно, где 1- номер блока)

0FDC76  

02AA56

               (пустая строка - значений может не быть!)

02AA56

…..   (аналогично)

7425AC  (последняя строка блока…. число строк постоянно= 25, т.е. наименование+24 строк данных)

Наим. блока 2

0С7593

02ВВ36

…..

6425AC   ( и так несколько блоков)

# (признак окончания файла)

Число блоков РАЗЛИЧНО, до 50 шт.

Эта часть задачи решена. Отправка по символьно с контролем символа окончания файла.

Нужны методы (черной скетч), как:

  1. Принять и оптимально разместить данные в массиве с запоминанием при выкл.питания.
  2. Выбрать соответствующую по параметрам памяти адруину.
  3. По номеру блока выводить на дисплее 16х2 его наименование
  4. По кнопке отправлять выбранный блок в порт так:

Serial.write(0хНомерБлока)

Serial.write(0х0F)  (как байт на примере блока 1)

Serial.write(0хDC) 

Serial.write(0х76) 

Serial.write(0хАС) 

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

dim3740 пишет:

2. Выбрать соответствующую по параметрам памяти адруину.

Если мне нужно изменить в сервере размер дискового пространства, то я меняю накопители, а не подбираю новый сервер.

Так что ардуина тут может быть всегда одна, самая минимальная.

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

Отлично! Готов к внешней памяти для массива, если внутренних ресурсов не хватит.  Даже у Меги?

Кстати, вариант с чтением с СД карты не устроит. Нужно именно КОМ соединение для заливки.

sadman41
Offline
Зарегистрирован: 19.10.2016

У меги хватит, но зачем... Щас внешней памяти развелось, как грязи. Хошь - на I2C сажай, хошь на SPI.

P.S. Соврал, у меги 4кб eeprom, не хватает полкило. Так что внешняя - полюбому. Или какой-нить STM брать, наверное. Не знаю их параметров.

24LC64 - на 64 килобита, что, если правильно прикинул, хватит с запасом на все варианты. Т.е. вообще девайсу не нужно ничего менять в железе - только пиши/читай.

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

Еще раз отлично! Тем более, что запас нужен))) Мб число блоков увеличится процентов на 20...  Ну кто возьмется, чтоб мне не танцевать с вопросами, которые я не знаю? Нет времени. Нужно решение. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Я могу накидать, если не горит прямо уж сильно. Надо только глянуть - есть у меня подобная микруха или нет. Вроде была. wrk.sadman@gmail.com

 

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

Написал.

Фи... памяти полно в магазине... счас куплю. 30 руб

b707
Offline
Зарегистрирован: 26.05.2017

так, ремарка :) - у меги ЕЕПРОМ хватит. 50 блоков * 25 строк * 3 байта = 3750 байт

это если строчки - 16-ричные числа. Если просто произвольные строки - то в 2 раза больше

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

так, ремарка :) - у меги ЕЕПРОМ хватит. 50 блоков * 25 строк * 3 байта = 3750 байт

Забыл, что название из 16-ти байт.

kez63
kez63 аватар
Offline
Зарегистрирован: 09.04.2013

Вопрос сколько циклов W/R планируется.  Ресурсы ЕЕПРОМ  большие но не бесконечные.

Лучше память магнитную ставить и быстродействие выше и ресурс на пару порядков выше.

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

Привожу свой скетч как основа. Нужно его сделать работающим. 

 // #include <EEPROM.h>

int Arr[1111];
int addr = 0;

int CarrentBlok;
int BlokMax;
int SmBlok; // смещения в массиве
int SmSection;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  // организация массива
  // блок1 - название 16 символов - устанавливается по нулевой кнопке
  // по кнопке 1 выводится:
  // префикс (1 байт) канала 1 + секция 1 (секция  - это 3 байта)
  // префикс канала 2 + секция 1
  // ...
  // префикса канала 6 + секция 1
  // аналогично по 2,3 и 4 кнопке, т.е.
  // по кнопке 4 выводится::
  // префикс канала 1 + секция 4
  // префикс канала 2 + секция 4
  //...
  // префикс канала 6 + секция 4

  //затем идет блок 2 ... аналогично... число блоков неизвестно, до 45

  if (digitalRead(0) == 0) // сначала выбираем блок. Номер блока дает смещение\начальную ячейку выборки. Блок = 16 байт название + 3байт х 4 секц х 6 кан =  16 + 72 = 88
    // тогда 4000 / 88 = до 45 блоков
  {
    if (CarrentBlok > BlokMax)
    {
      CarrentBlok = 0;  // максимум должен был определиться при чтении потока. Как?
    }
    SmBlok = CarrentBlok * 88;
    Serial.println(Arr[SmBlok]); 
    CarrentBlok++;
  }  // вывели название до 16 символов на монитор для отладки

  if (digitalRead(1) == 0) // получаем данные 1 секции по всем 6 каналам по выбранному блоку. Это 3х6 = 18 байт
  {
    SmSection = 0;  // смещение для данной секции... умножится на 18
    for (int x = 0; x < 18; x = x + 3) // 0 3 6 9 12 15  // цикл по каналам
    {
      int k = x / 3;
      Serial.println(k); // вывели префикс = номер канала  для отладки
      for (int y = 0; y < 3; y++)  // цикл по данным
      {
        int Dat = Arr[SmBlok + SmSection * 18 + y * x];
        Serial.println(Dat); // вывели данные в HEX для отладки
        Out(k, Dat, y); // для вывода в порт
      }
    }
  }

  if (digitalRead(2) == 0) // получаем данные 2 секции.....  вставить кнопки 3 и 4
  {
    SmSection = 1;
    for (int x = 0; x < 18; x = x + 3)
    {
      int k = x / 3;
      Serial.println(k); // вывели префикс = номер канала
      for (int y = 0; y < 3; y++)
      {
        int Dat = Arr[SmBlok + SmSection * 18 + y * x]; // секция сместилась на 18 байт.....вывели данные в HEX
        Serial.println(Dat); // вывели данные в HEX
        Out(k, Dat, y);
      }
    }
  }

  while (Serial.available() > 0)  //
  {
    char inChar = (char)Serial.read();   // в массиве могут быть пустые .....

    // inInt = преобразователь из inChar  HEХ

    //   Arr[addr] = inInt;
    addr++;

    //итого 2 массива : один для отладки без записи в ЕЕПРОМ без выключения, второй - на EEPROM
    
    // EEPROM.write(addr, inInt);
  }
}

void Out(int k, int Dat, int y)
{
  if (Dat) > NULL
  {
    if (y == 0)
    {
      Serial.write(0x k);
       Serial.write(0xDat);
    }
    if (y==1)
    {
      Serial.write(0x k+1);
      Serial.write(0xDat);
    }
    if (y==2)
    {
      Serial.write(0xk+2);
      Serial.write(0xDat);
    }
  }
}

10 циклов в неделю