УЦИ для токарного станка

Тема в разделе "Глядите, что я сделал", создана пользователем DIYMan, 29 дек 2018.

  1. DIYMan

    DIYMan Guest

    Короче, радость, как водится - была преждевременной: подключил вторую линейку, и заметил, что при одновременном движении двух линеек иногда показания с одной отрисовываются неправильно. То ли я где-то очень долго в прерываниях сижу, то ли - одно из двух, надо выяснять. Вроде и отрисовка идёт с учётом того, что используются прерывания, и код максимально неблокирующим сделал - всё равно чего-то не хватает. Отрисовка на TFT, без FSMC - жутко тормозная вещь, к слову: хотя предварительная оптимизация отрисовки уже проведена, и перерисовываются только изменившиеся разряды - всё равно хочется быстрее. Почему иногда отрисовываются не те данные - тоже хз: синхронизация в прерываниях по началу фрейма тактирования - есть, чего этой хороняке надо - в непонятках :( Но ясно, что проблема именно в отрисовке, как минимум. Буду разбираться.

    Может, дело ещё в макетке - как обычно, половина на соплях, поэтому делать какие-то выводы - сложно :)

    Короче, работы ещё валом, не знаю, справлюсь ли. На одну линейку-то - всё без нареканий, но мне нужно минимум две.
     
    Последнее редактирование модератором: 28 апр 2019
    DetSimen нравится это.
  2. DIYMan

    DIYMan Guest

    Может, кто свежим взглядом взглянет, возможно, дело тупо в помехах, потому что: отключил полностью первую ось, оставил только вторую. Т.е. прерывание только одно, куда уж меньше. Двигаю линейку, а там проскакивают вот такие артефакты (видно, что значение ВНЕЗАПНО стало больше, потом - вернулось на нормальное; двигаю линейку довольно плавно):
    Код (Text):
    Scale data: 1 0 1 0 1 1 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 ; raw=19381; formatted=9690
    Scale data: 1 0 1 0 0 1 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 ; raw=19365; formatted=9682
    Scale data: 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 ; raw=20469; formatted=10234
    Scale data: 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 ; raw=20469; formatted=10234
    Scale data: 1 0 1 0 0 1 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 ; raw=19749; formatted=9874
    Scale data: 1 0 1 0 0 1 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 ; raw=19749; formatted=9874
     
    Значение formatted - в сотых долях миллиметра, raw - это чиселка с битовыми полями, снятыми в прерывании. Код обработчика прерываний - крайне простой:
    Код (C++):
     // это прерывание вызывается по изменению уровня. Здесь надо понять, что мы можем начинать читать значения.
      uint8_t level = digitalRead(clockPin);
     
      if(level == LOW)
      {
        if(micros() - lastCaliperHighTime > 80000) // низкий уровень впервые за долгое время, это начало фрейма
        {
          // начало порции данных, подготавливаем переменные
          dataToRead = 0;
          caliperBitNumber = 0;
        }

          uint8_t readedCaliperBit = digitalRead(dataPin);
          dataToRead |= ( readedCaliperBit << caliperBitNumber );
          caliperBitNumber++;

          if(caliperBitNumber == 24) // всё прочитали, сигнализируем об этом
          {    
            caliperBitNumber = 0; // обнуляем счётчик бит, в следующий раз читать начнём сначала
            caliperDataReady = true;      
          }
      }  //if(level == LOW)
      else
      {
         // высокий уровень, запоминаем время
         lastCaliperHighTime = micros();
      }
    Всё, ничего космического нет, откуда артефакты - хз. Посмотрите трезвым взглядом - шо не так. Оборачивание в noInterrupts()/interrupts при копировании данных для вывода - не помогает. Тестовые данные вывожу в Serial вне прерывания, тупо по флагу caliperDataReady:
    Код (C++):
    if(caliperDataReady) // данные готовы, быренько их копируем к себе
              {
             
                //noInterrupts();
                caliperDataReady = false;
                int32_t thisData = dataToRead;
                uint8_t thisBitNumber = caliperBitNumber;
                //interrupts();
             
             
                if(thisBitNumber == 0)
                {
                  lastDataReadyAt = millis(); // запоминаем, когда пришли последние данные

                  // в thisData у нас лежит битовый массив, который надо преобразовать в значение в сотых долях миллиметра
                  int32_t formattedData = 0;

                  // форматируем значение
                  for(uint8_t i=1;i<=20;i++)
                  {              
                    formattedData +=  pow(2, i-1) * ( thisData & (1 << i) ? 1 : 0  );
                  }          

                  // знак лежит в 22-м бите
                  if(thisData & (1 << 21))
                    formattedData *= -1;

                  // остальные биты - нам пох, потому что линейка, которая у меня - выдаёт значение в сотых долях миллиметра, именно так мы и храним
               
                  bool hasChanges = (formattedData != rawData);            
                  rawData = formattedData;    

                  #ifdef _DEBUG

                    String s;
                    for(uint8_t i=0;i<24;i++)
                    {
                      if(thisData & (1 << i))
                        s += '1';
                      else
                        s += '0';

                      s += ' ';
                    } // for
                    DBG(F("Scale data: "));
                    DBG(s);
                    DBG(F("; raw="));
                    DBG(thisData);
                    DBG(F("; formatted="));
                    DBGLN(formattedData);
                 
                  #endif // _DEBUG
               
             
                  if(hasChanges) // были изменения, сигнализируем
                  {
                    Events.raise(this,EventScaleDataChanged,this);
                  }    

                } // thisBitNumber == 0
             
              } // caliperDataReady
    И вижу в порту указанные артефакты. Шо делать?
     
    DetSimen нравится это.
  3. DIYMan

    DIYMan Guest

    Похоже, пока вопрос снимается: пошевелил чуть конструкцию, на второй линейке проскочили артефакты. Походу - только после пайки будет ясно, что к чему. Будем делать тестовую плату, чо уж там - попадать на бабло так попадать :)

    Всем спасибо за участие, как видите - форум крайне полезен: стоит только написать - и сразу понятно, в чём причина :)))
     
    DetSimen нравится это.
  4. DetSimen

    DetSimen Guest

    нудакёптать.
     
    DIYMan нравится это.