Я пытаюсь использовать в своей конструкции индикатор: 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%)
Похоже мы с Вами никогда не договоримся, Вы не хотите слышать меня. Я плохо знаю систему команд, прошу лишь сместить диапазон измерения...