Меню на 7 сегментном индикаторе

Всем привет, есть у кого пример простого меню на 7 сегментном индикаторе??? У меня есть код отображения цифр и он рабочий, если его вызывать в loop:

void displayDigit()
{
  if ((t11>=0) && (t11<=9))  {digitalWrite(DIGIT_1PIN,LOW); digitalWrite(DIGIT_2PIN,HIGH); show_number(t11); delay(15);}
  if ((t11>=10) && (t11<=59)) 
  {  
          int a = t11/10;
            digitalWrite(DIGIT_2PIN,LOW);
            digitalWrite(DIGIT_1PIN,HIGH);
            show_number(a);
            delay(5);
          int b = t11%10;
            digitalWrite(DIGIT_2PIN,HIGH);
            digitalWrite(DIGIT_1PIN,LOW);
            show_number(b);
            delay(5);
  }      
  if (t11>59){t11=0;}
}
void loop() {
  butt2.tick();
   
  //кнопка UP
  if (butt2.isSingle()) { t11++; }
  displayDigit();
}

Но я хочу сделать что-то типа меню с кнопкой mode, set и как только я пишу код:

  if (butt2.isSingle()) { t11++;   displayDigit();}

то счетчик увеличивается, а отображается только последняя цифра. Как такое исправить??? Для опроса кнопок использую GyverButton.h СПАСИБО

А код где?

Ну, и в чём проблема? Что означает

Можно как-то попонятнее, что должно быть и и что есть?

Кажется, дошло. У Вас горит только та цифра, которую Вы последней выводили, так?

Разобрался ))) Тему можно удалять

А нафига вы все сообщения поудаляли? А если потом придет еще кто-то с этим же вопросом? Что, форум только для вас?
Некрасиво.
Давайте-ка обратно все восстановите

1 лайк

Да, он просто один из общих пинов (DIGIT_1PIN) забыл объявить OUTPUT.

Но, он ещё вернётся с вопросом “Почему дёргается?”. Динамическая индикация через луповский цикл с делеями - это сильно!

Вполне работоспособно, там делей то нужен всего один на 500 микросекунд)))) Проверял на себе )))

Частный случай. Ну, это наиболее примитивно и наглядно. Зачастую так и пользуюсь. А вообще, удобнее что бы индикация обслуживалась через прерывания. Тогда ни о чём не думай.

Полностью согласен!

О volatile токо не забывать.)
Конечно, здесь тоже нюансики есть. Если хочется быстро (500 мкс, например), то функции нежелательно использовать и т.п.

Отвечаю всем и выкладываю код который на данный момент есть как есть! Удалил, т.к. получилось несколько сообщений как-будто сам с собой поговорил ))) вот их и удалил. Код не идеален, но пока иду медленными шагами к созданию менюшки и работы вообще с 7 сегментниками.

‘’’
#include “GyverButton.h”
#include “GyverTimer.h”

#define segmentA 2
#define segmentB 3
#define segmentC 4
#define segmentD 5
#define segmentE 6
#define segmentF 7
#define segmentG 8

#define DIGIT_1PIN 9 //(4)
#define DIGIT_2PIN A0 //(3)
#define DIGIT_3PIN 11 //(2)
#define DIGIT_4PIN 12 //(1)

#define BTN_PIN1 A1 //кнопка режим
#define BTN_PIN2 A2 // кнопка UP
#define BTN_PIN3 A3 // кнопка DOWN
#define BTN_PIN4 A4 // кнопка SET

GButton butt1(BTN_PIN1);
GButton butt2(BTN_PIN2);

void setTimeout(uint16_t timeout);

int t11 = 57;
int t12 = 7;
int t21 = 7;
int t22 = 7;

int numMenu = 0;

// This function displays numbers from 0 to 9
void show_number(int num)
{
switch(num)
{
case 0:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, HIGH);
break;
case 1:
digitalWrite(segmentA, HIGH);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, HIGH);
break;
case 2:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, HIGH);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, LOW);
break;
case 3:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, LOW);
break;
case 4:
digitalWrite(segmentA, HIGH);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
break;
case 5:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, HIGH);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
break;
case 6:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, HIGH);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
break;
case 7:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, HIGH);
break;
case 8:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
break;
case 9:
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, HIGH);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
break;
default:
digitalWrite(segmentA, HIGH);
digitalWrite(segmentB, LOW);
digitalWrite(segmentC, LOW);
digitalWrite(segmentD, LOW);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, HIGH);
digitalWrite(segmentG, LOW);
break;
}
}

void show_f(){
digitalWrite(segmentA, LOW);
digitalWrite(segmentB, HIGH);
digitalWrite(segmentC, HIGH);
digitalWrite(segmentD, HIGH);
digitalWrite(segmentE, LOW);
digitalWrite(segmentF, LOW);
digitalWrite(segmentG, LOW);
}

void displayNameMode()
{
show_f();
digitalWrite(DIGIT_2PIN,LOW);
digitalWrite(DIGIT_1PIN,HIGH);
delay(5);
digitalWrite(DIGIT_2PIN,HIGH);
digitalWrite(DIGIT_1PIN,LOW);
show_number(3);
delay(5);

}

void displayTime(){
digitalWrite(DIGIT_2PIN,LOW);
digitalWrite(DIGIT_1PIN,HIGH);
show_number(0);
delay(5);
digitalWrite(DIGIT_2PIN,LOW);
digitalWrite(DIGIT_1PIN,HIGH);
show_number(0);
delay(5);
}

void displayDigit()
{
if ((t11>=0) && (t11<=9)) {digitalWrite(DIGIT_1PIN,LOW); digitalWrite(DIGIT_2PIN,HIGH); show_number(t11); delay(15);}
if ((t11>=10) && (t11<=59))
{
int a = t11/10;
digitalWrite(DIGIT_2PIN,LOW);
digitalWrite(DIGIT_1PIN,HIGH);
show_number(a);
delay(5);
int b = t11%10;
digitalWrite(DIGIT_2PIN,HIGH);
digitalWrite(DIGIT_1PIN,LOW);
show_number(b);
delay(5);
}
if (t11>59){t11=0;}
}

void setup() {
Serial.begin(9600);
pinMode(segmentA , OUTPUT);
pinMode(segmentB , OUTPUT);
pinMode(segmentC , OUTPUT);
pinMode(segmentD , OUTPUT);
pinMode(segmentE , OUTPUT);
pinMode(segmentF , OUTPUT);
pinMode(segmentG , OUTPUT);
pinMode(DIGIT_1PIN,OUTPUT);
pinMode(DIGIT_2PIN,OUTPUT);

pinMode(A1, INPUT_PULLUP);
pinMode(A2, INPUT_PULLUP);
}

void loop() {
butt1.tick();
butt2.tick();

switch (numMenu) {
case 0: displayNameMode(); break;
case 1: displayDigit(); break;
}

//выбор меню
if (butt1.isPress()) { numMenu++; if (numMenu==2) numMenu=0;}

//кнопка UP
if (butt2.isPress()) { t11++; tone(10, 1000); delay(50); noTone(10); }
}
‘’’

Понимаю, что код можно и нужно упрощать в десятки раз, но пока делаю в тупую, далее видно будет. Просто как-то странно, что на просторах сети нет примеров по типу менюшек на 7 сегментниках, отображение часов и прочего полно, а вот с выбором режимов и прочего - как-то не нашел, или есть но на asm )))

Ответил ниже )

delay надо будет переделать на миллис, с прерываниями пока посмотрим, ничего там сверх такого не планирую. Думаю миллис в будущем хватит.

Код не вставился нормально, поправьте.

Сам, будучи начинающим, тоже не мог найти…
https://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/prostoe-menyu
Подчеркну, это не пример для подражания, а код новичка

1 лайк

Обязательно. Начните с функции show_number(), а то эти бесконечные одинаковые кейсы выглядят убого.
Каждый сегмент можно обозначить одним битом, соответственно конфигурация сегментов для одного символа поместится в байт. Байты можно положить а массив и проиндексировать по номеру символа - итого вся функция сократится до десятка строк

Как то давненько писал код под шестипиновый трехрегистровый семисегментный индикатор.
Все сегменты (23шт) подключены посредством чарлиплексинга к 6 выводам .
Код получился нифига не маленький.


#include <avr/interrupt.h>
#include <avr/io.h>
#define nPIN 6
#define nREG 3
#define nSEG 8

//byte pinArr[6]={14,15,16,17,18,19};

//массив всех диодов {анод,катод}
const byte diodArr[nREG][nSEG][2]={
    {{2,3},{2,4},{5,2},{2,6},{2,5},{3,2},{4,2},{2,1}        
    },
    {{5,4},{3,5},{4,5},{3,4},{6,3},{4,3},{5,3},{3,1}        
    },
    {{1,6},{3,6},{5,6},{6,4},{4,6},{6,5},{1,5},{10,10}       
    }
};

#define space 10
const byte simbol[12]{//abcdefgDp
    0b11111100,//0
    0b01100000,//1
    0b11011010,//2
    0b11110010,//3
    0b01100110,//4
    0b10110110,//5
    0b10111110,//6
    0b11100000,//7
    0b11111110,//8
    0b11110110, //9    
    0b00000000,//space
    0b11101110,//A
};

byte value[3]={0,0,8};
byte stepDir[nPIN];
byte stepState[nPIN];
byte _stepDir[nPIN];
byte _stepState[nPIN];
float count=0;
boolean dot1=0,dot2=1;
volatile byte step=0;

void Calc(){    
    for(int i=0;i<nPIN;i++){/*
  количество шагов равняется количеству пинов.
 каждый шаг увеличивает номер вывода на который будет подаватся +5в на 1.
сначала смотрим вывод 1, потом 2 и тд  
        */
        //обнуляем массивы
        _stepDir[i]=0;
        _stepState[i]=0;
        
 for(int reg=0;reg<nREG;reg++){//для каждого из трех регистров
    for(int j=0;j<nSEG;j++){//по каждому из 8 сегментов (точка 8ой)
 //для вывода точек берем значение из массива знаков и работаем сним
 byte simbolCurrent=simbol[value[reg]];
 //если регистр самый левый добавляем к выводимому символу значение точки
                 if(reg==0)simbolCurrent=simbolCurrent+dot1;
//то же со средним регистром
if(reg==1)simbolCurrent+=dot2;
//если в текущей итерации сегмента нужно выводить то смотрим следующее условие
  if((simbolCurrent>>(nSEG-1-j))&1){
/*смотрим совпадает ли номер вывода текущего диода с текущим шагом
                    */
       if(diodArr[reg][j][0]==i+1){
                        /*
      если есть совпадение то по тогда пинаем в значение шага единичку на глубину указанную в массиве пинов
 то же для катода этого же диода , но плюс подаем только на анод
                        */
_stepDir[i]|=1<<(diodArr[reg][j][0]-1);
_stepDir[i]|=1<<(diodArr[reg][j][1]-1);
_stepState[i]|=1<<(diodArr[reg][j][0]-1);            }
  }
            }
   }
        }
    cli();
    //копируем из временного массива в массив вывода предварительно отключив прерывание
   memcpy(stepDir,_stepDir,nPIN);
   memcpy(stepState,_stepState,nPIN);
    sei();
}

ISR(TIMER1_COMPA_vect){
    
    DDRC=stepDir[step];
    PORTC=stepState[step];
   
    step==nPIN-1?step=0:step++;
}

void setup(){
    TCCR1A=0;
    TCCR1B=0;
    OCR1A=100;
    TCCR1B|=1<<WGM12;
    TCCR1B|=1<<CS11;
    TIMSK1|=1<<OCIE1A;
    sei();
}

void loop(){    
   static uint32_t calcTime=millis();
       int outVal=0;
    if(count<10){
        dot1=1;
        dot2=0;
        outVal=count*100;
    }else if(count<100){
        dot1=0;
        dot2=1;
        outVal=count*10;
    }
    
    value[0]=outVal/100;
    value[1]=(outVal/10)%10;
    value[2]=outVal%10;
   if(millis()-calcTime>=200){
        calcTime=millis();
        Calc();
        count+=0.01;
    }            
}

Мне вообще непонятно, как меню связано с типом индикатора.
Если разработано меню, то оно должно работать на любом индикаторе, удовлетворяющем минимальным требованиям.
Что же касается индикатора, то он должен уметь отображать нужную информацию. С задачами меню это никак не связано.
Вопрос похож на “как построить маршрут между домом и магазином при поездке на Жигулях желтого цвета?” Как будто, если Жигули будут другого цвета, то и маршрут будет другой.

Так и есть, меню и индикация - разные вещи.
Они связаны только в голове у новичков, именно динамическая индикация и меню, особенно с миганием выделяемых разрядов, у меня тоже вызывали сложности…))

Вас, старослужащих, хрен поймёшь! Не напишешь, какая машина - вопите, “Почему не написал, а вдруг у тебя грузовик, а так знак “грузовикам низзя””. Напишешь чё за машина подробно - “Нафига писал, какая разница какого она цвета?”. И куда бедному духу бежать? Вы бы уж там все определились!

К слову - вполне вероятен другой маршрут.

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