Изменить прошивку Ардуино

Я пытаюсь использовать в своей конструкции индикатор: httpswww.instructables.comArduino-sketch-for-a-retro-analogue-meter-graphic-
Запустил его, довольно красивый, изменил надписи на шкале, на это ума хватило, но нужно изменить диапазон измерения – для этого уже ума не хватает. Кто ни будь сможет помочь? По запросу могу предоставить скетч, файл в Протеусе.

Ваша тема перемещена. Пожалуйста, используйте английский язык в англоязычных разделах форума.

Покажите изображение диапазона, который вы видите сейчас. Опишите диапазон, который вы хотите иметь. Покажите свой эскиз.

(Я исправил вашу неработающую ссылку)

Show a picture of the range you see now. Describe the range you want to have. Show your sketch. (I fixed your broken link)

Есть код для ардуино мега. Он создает изображение стрелочного прибора на tft индикаторе. Сейчас он меряет напряжение 0-5в на токоизмерительном резисторе, включенном в цепь выходной лампы усилителя, при этом стрелочный прибор показывает правильно, а цифровой 0-100mA.
Нужно что бы он мерял напряжение 0-5в на токоизмерительном резисторе правильно. Это напряжение будет меняться от 0 до 5 вольт, на экране при этом показания должны изменяться в диапазоне 0-100-200-300-400-500 mA и на стрелочном индикаторе (нужно изменить шкалу), и на семисегментном.


/*
 An example analogue meter using a ILI9341 TFT LCD screen

 This example uses the hardware SPI only and a board based
 on the ATmega328

 Needs Fonts 2, and 7 (also Font 4 if using large scale label)

 Comment out lines 153 and 197 to reduce needle flicker and
 to remove need for Font 4 (which uses ~8k of FLASH!)
 
 Alan Senior 23/2/2015
 */

// These are the connections for the UNO to display
#define sclk 52  // Don't change
#define mosi 51  // Don't change
#define cs   10                 
#define dc   9   
#define rst  8  

// If cs and dc pin allocations are changed then
// comment out #define F_AS_T line in "Adafruit_ILI9341_FAST.h"
// (which is inside "Adafriit_ILI9341_AS" library)
// Can alternatively connect this to the Arduino reset

//Если распределение выводов cs и dc изменено, то
//закомментируйте строку #define F_AS_T в "Adafruit_ILI9341_FAST.h"
//(которая находится внутри библиотеки "Adafriit_ILI9341_AS")
//C:\Users\W7-64-Эрз\Documents\Arduino

#include <Adafruit_GFX_AS.h>     // Core graphics library
#include <Adafruit_ILI9341_AS.h> // Fast hardware-specific library
#include <SPI.h>

#define ILI9341_GREY 0x5AEB

Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(cs, dc, rst); // Invoke custom library

float ltx = 0;    // Saved x coord of bottom of needle  Сохраненная x-координата нижней части иглы
uint16_t osx = 120, osy = 120; // Saved x & y coords  Сохраненные координаты x и y
uint32_t updateTime = 0;       // time for next update

int old_analog =  -999; // Value last displayed Последнее отображаемое значение
int old_digital = -999; // Value last displayed


void setup(void) {
  tft.init();
  tft.setRotation(2);

  tft.fillScreen(ILI9341_BLACK);

  tft.setTextColor(ILI9341_WHITE);  // Text colour
 // tft.drawCentreString("mA", 120, 270, 4);  //текст,,лево/право,,верх/низ,, что такое 4 - не знаю

 //Рисуем линию (x1, y1, x2, y2)
  tft.drawLine(0, 190, 240, 190,ILI9341_WHITE);


  analogMeter(); // Draw analogue meter
  
  digitalMeter(); // Draw digital meter

  updateTime = millis(); // Next update time  Время следующего обновления
}






void loop() {
  if (updateTime <= millis()) {
    updateTime = millis() + 500;

    int reading = 0;
    reading = random(-50, 151); // Test with random value Тест со случайным значением 
   
    reading = map(analogRead(A0),0,1023,0,100); // Test with value form Analogue 0  Тест с формой значения Аналог 0
    // reading = map(analogRead(A0),0,1023,0,500); // Test with value form Analogue 0
   
    showDigital(reading); // Update digital reading
    
    plotNeedle(reading, 8); // Update analogue meter, 8ms delay per needle increment        
    //Обновление аналогового счетчика, задержка 8 мс на шаг стрелки
    
  }
}


// #########################################################################
//  Draw the analogue meter on the screen   Нарисуйте аналоговый счетчик на экране
// #########################################################################
void analogMeter()
{
  // Meter outline
  tft.fillRect(0, 0, 239, 126, ILI9341_GREY);
  tft.fillRect(5, 3, 230, 119, ILI9341_WHITE);
  
  tft.setTextColor(ILI9341_BLACK);  // Text colour
  
  // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
  // Рисовать деления каждые 5 градусов от -50 до +50 градусов (100 градусов. Размах FSD)
 
  
  for (int i = -50; i < 51; i += 5) {     //было += 5
    // Long scale tick length
    int tl = 15;
    
    // Coodinates of tick to draw   Координаты точки для рисования
    float sx = cos((i - 90) * 0.0174532925);
    float sy = sin((i - 90) * 0.0174532925);
    uint16_t x0 = sx * (100 + tl) + 120;
    uint16_t y0 = sy * (100 + tl) + 140;
    uint16_t x1 = sx * 100 + 120;
    uint16_t y1 = sy * 100 + 140;
    
    // Coordinates of next tick for zone fill Координаты следующего тика для заполнения зоны
    float sx2 = cos((i + 5 - 90) * 0.0174532925);
    float sy2 = sin((i + 5 - 90) * 0.0174532925);
    int x2 = sx2 * (100 + tl) + 120;
    int y2 = sy2 * (100 + tl) + 140;
    int x3 = sx2 * 100 + 120;
    int y3 = sy2 * 100 + 140;
    
    // GREEN zone limits
    if (i >= -50 && i < -10) {
      tft.fillTriangle(x0, y0, x1, y1, x2, y2, ILI9341_GREEN);
      tft.fillTriangle(x1, y1, x2, y2, x3, y3, ILI9341_GREEN);
    }
    
    // RED zone limits
    if (i >= -10 && i < 50) {
      tft.fillTriangle(x0, y0, x1, y1, x2, y2, ILI9341_RED);
      tft.fillTriangle(x1, y1, x2, y2, x3, y3, ILI9341_RED);
    }
   
    // Short scale tick length  Длина короткой шкалы
    if (i % 25 != 0) tl = 8;
    
    // Recalculate coords incase tick lenght changed  Пересчитать координаты в случае изменения длины тика
    x0 = sx * (100 + tl) + 120;
    y0 = sy * (100 + tl) + 140;
    x1 = sx * 100 + 120;
    y1 = sy * 100 + 140;
    
    // Draw tick
    tft.drawLine(x0, y0, x1, y1, ILI9341_BLACK);
    
    // Check if labels should be drawn, with position tweaks
    // Проверьте, следует ли рисовать метки, с корректировкой положения
    if (i % 25 == 0) {
      // Calculate label positions  Рассчитать позиции этикеток
      x0 = sx * (100 + tl + 10) + 120;
      y0 = sy * (100 + tl + 10) + 140;
  
  switch (i / 25) {     //выключатель(не надо трогать)
       case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
       case -1: tft.drawCentreString("125", x0, y0 - 9, 2);break; 
       case 0: tft.drawCentreString("250", x0, y0 - 6, 2); break; 
       case 1: tft.drawCentreString("375", x0, y0 - 9, 2); break; 
       case 2: tft.drawCentreString("500", x0, y0 - 12, 2); break;//цифры на шкале            

  
      }
    }
    
    // Now draw the arc of the scale  Теперь нарисуйте дугу шкалы
    sx = cos((i + 5 - 90) * 0.0174532925);
    sy = sin((i + 5 - 90) * 0.0174532925);
    x0 = sx * 100 + 120;
    y0 = sy * 100 + 140;
    // Draw scale arc, don't draw the last part Нарисуйте масштабную дугу, последнюю часть не рисуйте.
    if (i < 50) tft.drawLine(x0, y0, x1, y1, ILI9341_BLACK);
  }
  
  tft.drawString("mA", 5 + 230 - 40, 119 - 20, 2); // Units at bottom right  Единицы измерения внизу справа
  //tft.drawCentreString("mA", 120, 70, 4); // Comment out to avoid font 4  Закомментируйте, чтобы избежать шрифта 4
  tft.drawRect(5, 3, 230, 119, ILI9341_BLACK); // Draw bezel line Нарисуйте линию рамки
  
  plotNeedle(0,0); // Put meter needle at 0 Поставьте стрелку счетчика на 0
}

// #########################################################################
// Update needle position
// This function is blocking while needle moves, time depends on ms_delay
// 10ms minimises needle flicker if text is drawn within needle sweep area
// Smaller values OK if text not in sweep area, zero for instant movement but
// does not look realistic... (note: 100 increments for full scale deflection)
// Обновить положение иглы
// Эта функция блокируется, пока игла движется, время зависит от ms_delay
// 10 мс минимизируют мерцание иглы, если текст нарисован в области развертки иглы
// Меньшие значения допустимы, если текст не находится в области развертки, ноль для мгновенного движения, но
// выглядит нереалистично... (примечание: 100 приращений для отклонения в полном масштабе)
// #########################################################################
void plotNeedle(int value, byte ms_delay)
{
  tft.setTextColor(ILI9341_BLACK, ILI9341_WHITE);
  char buf[8]; dtostrf(value, 4, 0, buf);
  tft.drawRightString(buf, 40, 119 - 20, 2);

  if (value < -10) value = -10; // Limit value to emulate needle end stops  Предельное значение для эмуляции концевых остановок иглы
  if (value > 110) value = 110;

  // Move the needle util new value reached   Переместите стрелку, пока не будет достигнуто новое значение
  while (!(value == old_analog)) {
    if (old_analog < value) old_analog++;
    else old_analog--;
    
    if (ms_delay == 0) old_analog = value; // Update immediately id delay is 0  Обновить немедленно, задержка идентификатора равна 0
    
    float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle Значение карты соответствует углу
    // Calcualte tip of needle coords Рассчитать кончик игольного шнура
    float sx = cos(sdeg * 0.0174532925);
    float sy = sin(sdeg * 0.0174532925);

    // Calculate x delta of needle start (does not start at pivot point)  Рассчитайте x delta начала иглы (не начинается с точки поворота)
    float tx = tan((sdeg+90) * 0.0174532925);
    
    // Erase old needle image   Удалить старое изображение иглы
    tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, ILI9341_WHITE);
    tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, ILI9341_WHITE);
    tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, ILI9341_WHITE);
    
    // Re-plot text under needle  Перерисовать текст под иглой (в центре шкалы)
    tft.setTextColor(ILI9341_BLACK);
    tft.drawCentreString("mA", 120, 70, 4); // // Comment out to avoid font 4 Закомментируйте, чтобы избежать шрифта 4
    
    // Store new needle end coords for next erase Сохраните новые координаты конца иглы для следующего стирания
    ltx = tx;
    osx = sx * 98 + 120;
    osy = sy * 98 + 140;
    
    // Draw the needle in the new postion, magenta makes needle a bit bolder  
    // Нарисуйте иглу в новом положении, пурпурный цвет делает иглу немного жирнее.
    // draws 3 lines to thicken needle  рисует 3 линии, чтобы утолщать иглу
    tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, ILI9341_RED);
    tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, ILI9341_MAGENTA);
    tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, ILI9341_RED);

    
    // Slow needle down slightly as it approaches new postion Слегка замедлите движение иглы по мере приближения к новому положению.
    if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
    
    // Wait before next update  Подождите до следующего обновления
    delay(ms_delay);
  }
}

// #########################################################################
// Draw 3 digit digital meter with faint 7 segment image  Нарисуйте 3-значный цифровой счетчик с нечетким 7-сегментным изображением
// #########################################################################
void digitalMeter()
{
  int xpos = 118, ypos = 134; // was 134
  tft.fillRect(xpos - 52, ypos - 5, 2 * 54, 59, ILI9341_GREY);
  tft.fillRect(xpos - 49, ypos - 2, 2 * 51, 53, ILI9341_BLACK);
  tft.setTextColor(7 << 11, ILI9341_BLACK); // Plot over numbers in dim red
  tft.drawString("888", xpos - 48, ypos+1, 7);
}

// #########################################################################
// Update digital meter reading
// #########################################################################
void showDigital(int value)
{
  if (value==old_digital) return; // return if no change to prevent flicker
  if (value < 0) value = 0; //Constrain lower limit to 0
  if (value > 999) value = 999; //Constrain upper limit to 999
  
  int xpos = 118, ypos = 134+1; // Position with location tweak
  tft.setTextColor(7 << 11, ILI9341_BLACK); // Plot over numbers in dim red
  tft.drawString("888", xpos - 47, ypos, 7); //Erase old value
  
  // Nb. 32 pixels wide +2 gap per digit
  
  // Update with new value
  tft.setTextColor(ILI9341_RED); // Dont draw background to leave dim segments
  if (value < 10) tft.drawNumber(value, xpos+19, ypos, 7);
  else if (value < 100) tft.drawNumber(value, xpos - 14, ypos, 7);
  else tft.drawNumber(value, xpos - 47, ypos, 7);
  old_digital = value;
}

[Я использую переводчик]

Он берет показания и отображает их для отклонения от 0 до 100.

Если вы хотите отклонение от 0 до 500, измените его на это.

reading = map(analogRead(A0),0,1023,0,500);

чтение переводится в 7seg внутри showDigital()

Строка с измененным пределом в моем коде уже есть в "закомментированном виде" (100 на 500) При таком изменении стрелка зашкаливает, улетает в +, нужно еще что то где то менять. А еще нужно шкалу менять, очень неудобно 125, 375 миллиампер, да и цена деления неудобна.

Покажите, что вы изменили и исходную форму.

Какой вклад вы вносите в A0?

Вот отрывок кода:

73	void loop() {
74	  if (updateTime <= millis()) {
75	    updateTime = millis() + 500;
76
77	    int reading = 0;
78	    reading = random(-50, 151); // Test with random value Тест со случайным значением 
79   
80	    reading = map(analogRead(A0),0,1023,0,100); // Test with value form Analogue 0  
81	    // reading = map(analogRead(A0),0,1023,0,500); // Test with value form Analogue 0

В нем можно использовать строки 80 или 81. Входной сигнал изменяем от 0 до 5 вольт с помощью обычного потенциометра.В первом случае стрелочный индикатор работает правильно (стрелка показывает 0-500 mA), а семисегментный индикатор показывает от 0 до 100 mA.Во втором случае семисегментный 
индикатор показывает от 0 до 500 mA, но стрелка после 100 mA зашкаливает.Теперь все понятно? Да и саму шкалу нужно заменить на 0-100-200-300-400-500 mA.
В коде есть такие строчки:

103	 // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
104	  // Рисовать деления каждые 5 градусов от -50 до +50 градусов (100 градусов. Размах FSD)
105 
106  
107	  for (int i = -50; i < 51; i += 5) {     //было += 5

Я пробовал менять += 5 на += 4. Количество делений действительно увеличивается,но пропадают "длинные" деления и надписи 100-200-300-400.Посмотреть на все это "безобразие" не собирая схему можно в Протеусе, но я не знаю, используете Вы его или нет, если используете, то как и куда можно переслать файл.Могу заверить, файл хорошо воспроизводит реальную

схему.

Пожалуйста, никаких номеров линий. Пожалуйста, удалите текст из блока <CODE>

Таким образом, стрелка должна быть сопоставлена от 0 до 100, а ток — от 0 до 500.

`

Текст «как есть» (без применения форматирования)`	void loop() {
	  if (updateTime <= millis()) {
	    updateTime = millis() + 500;

	    int reading = 0;
	    reading = random(-50, 151); // Test with random value Тест со случайным значением 
  
	    reading = map(analogRead(A0),0,1023,0,100); // Test with value form Analogue 0  
	    // reading = map(analogRead(A0),0,1023,0,500); // Test with value form Analogue 0

введите или вставьте сюда код

103	 // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
104	  // Рисовать деления каждые 5 градусов от -50 до +50 градусов (100 градусов. Размах FSD)
105 
106  
107	  for (int i = -50; i < 51; i += 5) {     //было += 5

Я не понял, что Вы хотите.

Если (от 0 до 500) выходит за рамки шкалы, то шкала, вероятно, означает (от 0% до 100%)

Похоже мы с Вами никогда не договоримся, Вы не хотите слышать меня. Я плохо знаю систему команд, прошу лишь сместить диапазон измерения...