Помогите переделать код
- Войдите на сайт для отправки комментариев
Пнд, 05/12/2016 - 22:29
Я совсем новичек в ардуино, со светодиодами уже побаловался и теперь решил собрать что то по серьёзнее. Хочу собрать таймер на Ардуино и семисегментном дисплее. Готовый скетч нашёл в интернете но дело в том что он сделан под дисплей с общим Анодом, а у меня дисплей с общим Катодом. В связи с этим цифры отображаются не корректно, они показываются не горящими сегментами. Помогите мне переделать его под мой дисплей т.е под дисплей с общим Катодом.
#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);
}
Готовый скетч нашёл в интернете...
хреновое начало - пиши сам с нуля, никому не интересно оживлять дохлых котят.
Я еще не настолько всё освоил что бы написать такой сам. Хочу разобраться уже в готовом, но пока и это еще не совсем получается.
Я еще не настолько всё освоил что бы написать такой сам. Хочу разобраться уже в готовом, но пока и это еще не совсем получается.
предлагаешь тебя усыновить?
Так вы всё же хотите помочь или как? Я думал форум для того и существует что бы спросить совета у более опытных.
Так вы всё же хотите помочь или как? Я думал форум для того и существует что бы спросить совета у более опытных.
я более опытный - я тебе дал совет.
К сожалению он мне не помог.
Может кто то еще поможет, но уже делом а не филосовскими мыслями с чего должен начинать новичек.
Переверни элементы массива ind_digits[]. Допиши в каждой строчке сегменты тех которых нет, а которые есть выкини.
Я думал форум для того и существует что бы спросить совета у более опытных.
Правильно думал.
Вам дали самый правильный совет, который только может быть.
В этом скетче Вы не разберётесь, пока не напишете сами что-то подобное (ну, хоть наполовину). Не разберётесь потому, что языка Вы не знаете (иначе разобрались бы), читать не умеете (иначе прочитали бы как вставлять код - в таком виде его никто и смотреть не будет) и советов не слушаете.
Попробуйте последовать данному Вам совету. Это лучшее, что Вы можете сделать.
А в чем должна заключаться помощь? В том, чтобы сделать что-то вместо Вас? Так это не помочь, это, наоборот, помешать сделать самостоятельно.
Если Вы хотите чему-то научиться, то приведенный выше совет - то, что надо.
Если то, что Вы хотите сделать слишком сложно для Вас, выберите проект попроще.
Если Вы хотите сделать иметь готовый аппарат, затратив минимум собственных усилий - Вам в раздел "Ищу исполнителя".
Но заявление "Я нашел скетч, помогите переделать" - это однозначно путь в тупик.
Ребят вы конечно не обижайтесь но вот из всех кто тут писал реально помог только один человек это nik182, а все остальное это просто болтология. Я не прошу вас переделать код, я просто просил что бы вы направили меня в нужное русло, а вы просто читаете мораль. Вам жалко поделиться вашими ценными мыслями? Дали бы совет, напечатали бы ровно столько же текста.
Ребят вы конечно не обижайтесь но вот из всех кто тут писал реально помог только один человек это nik182, а все остальное это просто болтология. Я не прошу вас переделать код, я просто просил что бы вы направили меня в нужное русло, а вы просто читаете мораль. Вам жалко поделиться вашими ценными мыслями? Дали бы совет, напечатали бы ровно столько же текста.
мальчик, иди на паперть побираться.
Простите господин мега мозг, ещё один блестящий совет от вас услышал. Наверное последую ему.
из всех кто тут писал реально помог только один человек
Это лишь говорит о Вашей неспособности (или нежелании) принять помощь.
так в чём ваша помощь то заключилась? в том что вы мне указали на то что я пока еще плохо знаю аппаратную платформу? это я и так знаю. хочу научится ввней понимать, ваши советы помогли бы мне поскорее в этом разобраться.
Помогли бы, если бы Вы им следовали.
так в чём ваша помощь то заключилась? в том что вы мне указали на то что я пока еще плохо знаю аппаратную платформу? это я и так знаю. хочу научится ввней понимать, ваши советы помогли бы мне поскорее в этом разобраться.
Вам nic182 полтора часа назад дал направление, за это время уже все должно заработать, а вы еще здесь препираетесь. И смысл давать советы, которые вы не сможете воспринять, не зная ни языка, ни аппаратных средств.?????
Советом nic182 я воспользовался, ему за это большое спасибо! Только пока он и дал полезный совет. Всё действительно заработало, только не так как должно. Следуя его совету отображается всё кроме цифры 8, соответственно и последовательность программы нарушена, работает она не коректно. По правельному нужно поменять полюса питания сегментов, понимаю что где то нужно поменять местами HIGH и LOW, перепробовал уже всё, но где это сделать так чтобы всё правельно работало так и не нашол.
Последовательноть программы не может быть нарушена изменением не зависящих от программы данных. Этот массив есть данные для знако генератора. Для восьмёрки если выкинуть все, то ничего не останется, и нужно написать 0, чтобы размер массива остался прежним. Вам дали кучу правильных советов. Учиться.
Ноль писать пробовал, при компиляции выдаёт ошибку.
я просто просил что бы вы направили меня в нужное русло
Вас направили в нужное русло в первом же посте, но Вы этого не поняли.
Результат закономерен
перепробовал уже всё, но где это сделать так чтобы всё правельно работало так и не нашол
всё кроме цифры 8,
Во-во. Единицу попробуйте, потом двойку, на 100500, глядишь, и проскочит.
Может лучше всё-таки последовать доброму совету и научиться чему-нибудь?
Впрочем, дело Ваше, Вам жить.
Покажите массив ind_digits[] при котором компилятор давал ошибку. При вставке кода воспользуйтесь тегом код или прочитайте тему вставка кода в сообщение. На второй закладке есть галочка свернуть код. Очень помогает не мозолить глаза длинными листингами.
Ноль писать пробовал, при компиляции выдаёт ошибку.
И? Вы прочитали ошибку, котурую Вам написал компилятор?
И? Вы прочитали ошибку, котурую Вам написал компилятор?
Зачем её читать? Они ж все одинаковые! Там важен факт есть ошибка или нет. Алгоритм простой:
ЕСЛИ есть ошибка ТО топаем на форум
ИНАЧЕ убеждаемся, что оно компилируется, но не работает и всё равно топаем на форум.
Если посылать подальше советы чему-нибудь начиться, а только требовать "помощи", то по-другому-то не бывает.
Ноль писать пробовал, при компиляции выдаёт ошибку.
И? Вы прочитали ошибку, котурую Вам написал компилятор?
Я уверен, он прочитал. Было "error".
ПС. Зачем приставать к человеку, который даже код в тему не может нормально выложить с заумными вопросами ;)
Я добился своего. Спасибо nik182 за помощь. Тему можно закрывать.
Молодец!