Помогите переделать код

minimus
Offline
Зарегистрирован: 05.12.2016

Я совсем новичек в ардуино, со светодиодами уже побаловался и теперь решил собрать что то по серьёзнее. Хочу собрать таймер на Ардуино и семисегментном дисплее. Готовый скетч нашёл в интернете но дело в том что он сделан под дисплей с общим Анодом, а у меня дисплей с общим Катодом. В связи с этим цифры отображаются не корректно, они показываются не горящими сегментами. Помогите мне переделать его под мой дисплей т.е под дисплей с общим Катодом.

#include <EEPROM.h>
 
void setup() {
  ind_setup();
  kbd_setup();
  out_setup();
  config_setup();
}
 
void loop() {
  ind_refresh();
  ind_update();
  kbd_update();
  timer_update();
  out_update();
  config_update();
  beep_update();
  delay(10);
}
 
//Config///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct {
  unsigned long time;
  byte crc;
} config;
#define CONFIG_WRITE_DELAY 500
unsigned int config_timer;
void config_setup() {
  config_read();
  if (config.time > (3600 * 99)) config.time = 1;
}
void config_update() {
  if (config_timer > 0) {
    config_timer--;
    if (config_timer == 0) {
      config_write();
    }
  }
}
void config_read() {
  byte *b = (byte *)&config;
  for (byte i=0; i<sizeof(config); i++)
    *b++ = EEPROM.read(i);
}
void config_write() {
  byte *b = (byte *)&config;
  for (byte i=0; i<sizeof(config); i++)
    EEPROM.write(i, *b++);
}
void config_write_reset() {
  config_timer = CONFIG_WRITE_DELAY;
}
 
//Timing///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum {SEC,MINSEC,MIN,HR}; //time mode
const unsigned int timer_inc[] = {1,10,60,3600};
const unsigned long timer_mode_min[] = {0,60,10*60,60*60};
unsigned long timer = 0;
byte timer_div = 0;
//check if timer is loaded and counting
byte timer_counting() {
  return (timer > 0);
}
//get timer mode (0-seconds, 1-min.sec, 2-min, 3-hr)
byte timer_mode(unsigned long t) {
  if (t < 60) return SEC;
  else if (t < 10 * 60) return MINSEC;
  else if (t < 60 * 60) return MIN;
  else return HR;
}
//get 2-digit value for timer
byte timer_to_byte(unsigned long t) {
  switch (timer_mode(t)) {
    case SEC: return t;
    case MINSEC: return ((t / 60) * 10) + ((t % 60) / 10);
    case MIN: return (t / 60);
    case HR: return (t / 3600);
   }
}
//update timer
void timer_update() {
  if (timer_counting()) {
    if (++timer_div >= 100) {
      timer_div = 0;
      timer--;
      if (timer == 0) {
        //play stop sound
        beep_timer_end();
      } else {
        if (timer <= 10) beep_timer_ending();
      }
    }
  }
}
//set and start timer
void timer_start(unsigned long t) {
  timer = t;
  timer_div = 0;
}
 
//Indication///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum {SEGA=1,SEGB=2,SEGC=4,SEGD=8,SEGE=16,SEGF=32,SEGG=64,SEGH=128}; //segments masks
enum {SEGApin=2,SEGHpin=9}; //segments pins
//HEX 7-seg digits
const byte ind_digits[]={
  SEGA | SEGB | SEGC | SEGD | SEGE | SEGF, //0
  SEGB | SEGC, //1
  SEGA | SEGB | SEGD | SEGE | SEGG, //2
  SEGA | SEGB | SEGC | SEGD | SEGG, //3
  SEGB | SEGC | SEGF | SEGG, //4
  SEGA | SEGC | SEGD | SEGF | SEGG, //5
  SEGA | SEGC | SEGD | SEGE | SEGF | SEGG, //6
  SEGA | SEGB | SEGC, //7
  SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG, //8
  SEGA | SEGB | SEGC | SEGD | SEGF | SEGG, //9
  SEGA | SEGB | SEGC | SEGE | SEGF | SEGG, //A
  SEGC | SEGD | SEGE | SEGF | SEGG, //b
  SEGA | SEGD | SEGE | SEGF, //C
  SEGB | SEGC | SEGD | SEGE | SEGG, //d
  SEGA | SEGD | SEGE | SEGF | SEGG, //E
  SEGA | SEGE | SEGF | SEGG, //F
};
const byte ind_com[] = {10,A1}; //common anode pins
//number of digits
#define IND_SIZE 2
byte ind_buf[IND_SIZE]; //indication buffer
byte ind_cnt; //current digit counter
//setup indication
void ind_setup() {
  //segment pins
  for (byte pin=SEGApin; pin<=SEGHpin; pin++) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
  //common anodes pins
  for (byte pin=0; pin<IND_SIZE; pin++) {
    pinMode(ind_com[pin], OUTPUT);
    digitalWrite(ind_com[pin], LOW);
  }
  //clear buffer
  for (byte i=0; i<IND_SIZE; i++) ind_buf[i] = 0;
}
byte ind_digit(byte digit) {
  return ind_digits[digit];
}
//set segments
void ind_set_segs(byte digit) {
  byte mask = 1;
  for (byte pin=SEGApin; pin<=SEGHpin; pin++) {
    digitalWrite(pin, !(digit & mask));
    mask <<= 1;
  }
}
//select digit (0xFF to deselect all)
void ind_set_com(byte num) {
  if (num == 0xFF) { //all OFF
    for (byte com=0; com<IND_SIZE; com++) digitalWrite(ind_com[com], HIGH);
  } else {
    digitalWrite(ind_com[num], LOW);
  }
}
//convert lower half-byte to 7-segment HEX
byte to_hex(byte data) {
  return ind_digit(data & 0xF);
}
//convert decimal 0..99 to BCD 0..0x99
byte to_bcd(byte data) {
  byte result = data % 10;
  data /= 10;
  result += (data % 10) << 4;
  return result;
}
//write 8-bit HEX to indication buffer
void ind_wr_H8(byte data, byte pos) {
  ind_buf[pos] = to_hex(data >> 4);
  ind_buf[pos + 1] = to_hex(data);
}
//refresh indication
void ind_refresh() {
  ind_set_com(0xFF);
  if (++ind_cnt >= IND_SIZE) ind_cnt = 0;
  ind_set_segs(ind_buf[ind_cnt]);
  ind_set_com(ind_cnt);
}
void ind_update() {
  unsigned long t = (!timer_counting()) ? config.time : timer;
  ind_wr_H8(to_bcd(timer_to_byte(t)), 0);
  if (ind_buf[0] == ind_digits[0]) ind_buf[0] = 0;
  if (timer_div < 50) {
    switch (timer_mode(t)) {
      case SEC: break;
      case MINSEC: ind_buf[0] |= SEGH; break;
      case MIN: ind_buf[1] |= SEGH; break;
      case HR: ind_buf[0] |= SEGH; ind_buf[1] |= SEGH; break;
    }
  }
}
 
//Keyboard/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
byte kbd_buf[2]; //current/previous keyboard states
byte kbd_cnt; //keypress counter
enum {KBD_UP=1, KBD_DOWN=2, KBD_SET=3}; //key codes
enum {KBD_CNT_SHORT=5, KBD_CNT_LONG=100, KBD_CNT_START=250, KBD_REPEAT=10}; //key press counter values
#define KBD_CNT_REPEAT (KBD_CNT_LONG - KBD_REPEAT)
void kbd_setup() {
  pinMode(12, INPUT_PULLUP);
  digitalWrite(12, HIGH);
  pinMode(13, INPUT_PULLUP);
  digitalWrite(13, HIGH);
}
byte kbd_read() {
  return (!digitalRead(12) << 1) | !digitalRead(13);
}
byte kbd_press(byte code, byte cnt) {
    return (kbd_buf[1] == code) && (kbd_cnt == cnt);
}
byte kbd_press2(byte code, byte cnt1, byte cnt2) {
    return (kbd_buf[1] == code) && ((kbd_cnt == cnt1) || (kbd_cnt == cnt2));
}
void kbd_update(void) {
  kbd_buf[0] = kbd_read();
  if (kbd_buf[1] != kbd_buf[0]) {
    kbd_cnt = 0;
    kbd_buf[1] = kbd_buf[0];
  } else {
    if (kbd_cnt < 255) kbd_cnt++;
    if (!timer_counting()) {
      if (kbd_press2(KBD_UP, KBD_CNT_SHORT, KBD_CNT_LONG)) {
        if (kbd_cnt == KBD_CNT_LONG) kbd_cnt = KBD_CNT_REPEAT;
        else beep_key_press();
        config.time += timer_inc[timer_mode(config.time)];
        if (config.time > (3600UL * 99)) config.time = (3600UL * 99);
        config_write_reset();
        beep_stop();
      }
      else if (kbd_press2(KBD_DOWN, KBD_CNT_SHORT, KBD_CNT_LONG)) {
        if (kbd_cnt == KBD_CNT_LONG) kbd_cnt = KBD_CNT_REPEAT;
        else beep_key_press();
        if (config.time > 1) {
          byte m = timer_mode(config.time);
          if ((m > 0)&&(config.time == timer_mode_min[m])) m--;
          config.time -= timer_inc[m];
          config_write_reset();
        }
        beep_stop();
      }
      //start timer
      else if (kbd_press(KBD_SET, KBD_CNT_SHORT)) {
        timer_start(config.time);
        beep_stop();
        beep_timer_start();
      }
    } else {
      //stop timer
      if (kbd_press(KBD_SET, KBD_CNT_SHORT)) {
        timer = 0;
        beep_timer_stop();
      }
    }
  }
}
 
//Out/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define OUT_PIN A0
void out_setup() {
  pinMode(OUT_PIN, OUTPUT);
  digitalWrite(OUT_PIN, HIGH);
}
void out_update() {
  if (timer_counting()) digitalWrite(OUT_PIN, LOW);
  else digitalWrite(OUT_PIN, HIGH);
}
 
//Beeper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define BEEP_FREQ 2500
unsigned int beep_cnt;
void beep(byte len) {
  if (len == 0) noTone(11);
  else if (len == 1) tone(11, BEEP_FREQ);
  else tone(11, BEEP_FREQ, len);
}
void beep_stop() {
  beep_cnt = 0;
  beep(0);
}
void beep_update() {
  if (beep_cnt > 0) {
    beep_cnt--;
    if (beep_cnt == 0) beep(0);
    else {
//      beep((beep_cnt & 0x20) && (beep_cnt & 0x4) && (beep_cnt & 0x02));
      beep((beep_cnt & 0x40) && (beep_cnt & 0x08));
    }
  }
}
void beep_timer_end() {
  beep_cnt = 1000;
}
void beep_timer_start() {
  beep(100);
}
void beep_timer_stop() {
  beep(100);
}
void beep_timer_ending() {
  beep(50);
}
void beep_key_press() {
  beep(30);
}
 
Клапауций 234
Offline
Зарегистрирован: 24.10.2016

minimus пишет:

Готовый скетч нашёл в интернете...

хреновое начало - пиши сам с нуля, никому не интересно оживлять дохлых котят.

minimus
Offline
Зарегистрирован: 05.12.2016

Я еще не настолько всё освоил что бы написать такой сам. Хочу разобраться уже в готовом, но пока и это еще не совсем получается.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

minimus пишет:

Я еще не настолько всё освоил что бы написать такой сам. Хочу разобраться уже в готовом, но пока и это еще не совсем получается.

предлагаешь тебя усыновить?

minimus
Offline
Зарегистрирован: 05.12.2016

Так вы всё же хотите помочь или как? Я думал форум для того и существует что бы спросить совета у более опытных.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

minimus пишет:

Так вы всё же хотите помочь или как? Я думал форум для того и существует что бы спросить совета у более опытных.

я более опытный - я тебе дал совет.

minimus
Offline
Зарегистрирован: 05.12.2016

К сожалению он мне не помог.

minimus
Offline
Зарегистрирован: 05.12.2016

Может кто то еще поможет, но уже делом а не филосовскими мыслями с чего должен начинать новичек.

nik182
Offline
Зарегистрирован: 04.05.2015

Переверни элементы массива  ind_digits[]. Допиши в каждой строчке сегменты тех которых нет, а которые есть выкини. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

minimus пишет:

 Я думал форум для того и существует что бы спросить совета у более опытных.

Правильно думал.

Вам дали самый правильный совет, который только может быть.

В этом скетче Вы не разберётесь, пока не напишете сами что-то подобное (ну, хоть наполовину). Не разберётесь потому, что языка Вы не знаете (иначе разобрались бы), читать не умеете (иначе прочитали бы как вставлять код - в таком виде его никто и смотреть не будет) и советов не слушаете.

Попробуйте последовать данному Вам совету. Это лучшее, что Вы можете сделать.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А в чем должна заключаться помощь? В том, чтобы сделать что-то вместо Вас? Так это не помочь, это, наоборот, помешать сделать самостоятельно.

Если Вы хотите чему-то научиться, то приведенный выше совет - то, что надо.

Если то, что Вы хотите сделать слишком сложно для Вас, выберите проект попроще.

Если Вы хотите сделать иметь готовый аппарат, затратив минимум собственных усилий - Вам в раздел "Ищу исполнителя".

Но заявление "Я нашел скетч, помогите переделать" - это однозначно путь в тупик.

minimus
Offline
Зарегистрирован: 05.12.2016

Ребят вы конечно не обижайтесь но вот из всех кто тут писал реально помог только один человек это nik182, а все остальное это просто болтология. Я не прошу вас переделать код, я просто просил что бы вы направили меня в нужное русло, а вы просто читаете мораль. Вам жалко поделиться вашими ценными мыслями? Дали бы совет, напечатали бы ровно столько же текста.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

minimus пишет:

Ребят вы конечно не обижайтесь но вот из всех кто тут писал реально помог только один человек это nik182, а все остальное это просто болтология. Я не прошу вас переделать код, я просто просил что бы вы направили меня в нужное русло, а вы просто читаете мораль. Вам жалко поделиться вашими ценными мыслями? Дали бы совет, напечатали бы ровно столько же текста.

мальчик, иди на паперть побираться.

minimus
Offline
Зарегистрирован: 05.12.2016

Простите господин мега мозг, ещё один блестящий совет от вас услышал. Наверное последую ему.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

minimus пишет:

 из всех кто тут писал реально помог только один человек

Это лишь говорит о Вашей неспособности (или нежелании) принять помощь.

minimus
Offline
Зарегистрирован: 05.12.2016

так в чём ваша помощь то заключилась? в том что вы мне указали на то что я пока еще плохо знаю аппаратную платформу? это я и так знаю. хочу научится ввней понимать, ваши советы помогли бы мне поскорее в этом разобраться.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Помогли бы, если бы Вы им следовали.

bwn
Offline
Зарегистрирован: 25.08.2014

minimus пишет:

так в чём ваша помощь то заключилась? в том что вы мне указали на то что я пока еще плохо знаю аппаратную платформу? это я и так знаю. хочу научится ввней понимать, ваши советы помогли бы мне поскорее в этом разобраться.

Вам nic182 полтора часа назад дал направление, за это время уже все должно заработать, а вы еще здесь препираетесь. И смысл давать советы, которые вы не сможете воспринять, не зная ни языка, ни аппаратных средств.?????

minimus
Offline
Зарегистрирован: 05.12.2016

Советом nic182 я воспользовался, ему за это большое спасибо! Только пока он и дал полезный совет. Всё действительно заработало, только не так как должно. Следуя его совету отображается всё кроме цифры 8, соответственно и последовательность программы нарушена, работает она не коректно. По правельному нужно поменять полюса питания сегментов, понимаю что где то нужно поменять местами HIGH и LOW, перепробовал уже всё, но где это сделать так чтобы всё правельно работало так и не нашол.

nik182
Offline
Зарегистрирован: 04.05.2015

Последовательноть программы не может быть нарушена изменением не зависящих от программы данных. Этот массив есть данные для знако генератора. Для восьмёрки если выкинуть все, то ничего не останется, и нужно написать 0, чтобы размер массива остался прежним. Вам дали кучу правильных советов. Учиться.   

minimus
Offline
Зарегистрирован: 05.12.2016

Ноль писать пробовал, при компиляции выдаёт ошибку.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

minimus пишет:

я просто просил что бы вы направили меня в нужное русло

Вас направили в нужное русло в первом же посте, но Вы этого не поняли.

Результат закономерен

minimus пишет:

перепробовал уже всё, но где это сделать так чтобы всё правельно работало так и не нашол

Вы тычетесь как слепой котёнок без понимания, что делаете.
 
Вот сейчас у Вас возникла проблема

minimus пишет:

всё кроме цифры 8, 

Как только решите "проблему цифры 8", появится "проблема цифры 9", т.к. понимания как не было, так и нет.
 
minimus пишет:
Ноль писать пробовал, при компиляции выдаёт ошибку.

Во-во. Единицу попробуйте, потом двойку, на 100500, глядишь, и проскочит.

Может лучше всё-таки последовать доброму совету и научиться чему-нибудь?

Впрочем, дело Ваше, Вам жить.

nik182
Offline
Зарегистрирован: 04.05.2015

Покажите массив  ind_digits[] при котором компилятор давал ошибку. При вставке кода воспользуйтесь тегом код или прочитайте тему вставка кода в сообщение. На второй закладке есть галочка свернуть код. Очень помогает не мозолить глаза длинными листингами. 

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

minimus пишет:

Ноль писать пробовал, при компиляции выдаёт ошибку.

И? Вы прочитали ошибку, котурую Вам написал компилятор?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Jeka_M пишет:

И? Вы прочитали ошибку, котурую Вам написал компилятор?

Зачем её читать? Они ж все одинаковые! Там важен факт есть ошибка или нет. Алгоритм простой:

ЕСЛИ есть ошибка ТО топаем на форум
ИНАЧЕ убеждаемся, что оно компилируется, но не работает и всё равно топаем на форум.

Если посылать подальше советы чему-нибудь начиться, а только требовать "помощи", то по-другому-то не бывает.

Logik
Offline
Зарегистрирован: 05.08.2014

Jeka_M пишет:

minimus пишет:

Ноль писать пробовал, при компиляции выдаёт ошибку.

И? Вы прочитали ошибку, котурую Вам написал компилятор?

Я уверен, он прочитал. Было "error".

ПС. Зачем приставать к человеку,  который даже код в тему не может нормально выложить с заумными вопросами ;)

minimus
Offline
Зарегистрирован: 05.12.2016

Я добился своего. Спасибо nik182 за помощь. Тему можно закрывать.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Молодец!