O'zgaruvchan ismlarga matn qo'shish: Iltimos, ushbu kodni qisqartirishga yordam bering

Quyidagi "sozlash" ostida kodni qisqartirishga harakat qilaman, bu erda tashqi EEPROMdan o'qiladigan 120 dan ortiq o'zgaruvchiga ega bo'lganman. EEPROM manzilining manzilini saqlaydigan o'zgarmaydigan mavjud bo'lgan o'zgaruvchining nomini, shuningdek, "Pos" so'zini ifodalaydi.

byte fanSpeed, nl1Toggle, ledsToggle;
byte fanSpeedPos = 12, nl1TogglePos = 95, ledsTogglePos = 7;

void setup() {
  fanSpeed = readEE(fanSpeedPos);
  nl1Toggle = readEE(nl1TogglePos);
  ledsToggle = readEE(ledsTogglePos);
  //there are over 120 of the above readEE statements in the actual code.
}

uint8_t readEE(uint8_t entry) {
  readEEPROM(AT24C32_ADDRESS, 1, entry);
}

Ideal holda men buni shunday qilishni xohlayman (pseudo kodini ishlataman, chunki buni amalga oshirishni bilmayman):

char* variableNames [] = { "fanSpeed", "nl1Toggle", "ledsToggle" };
byte fanSpeedPos = 12, nl1TogglePos = 95, ledsTogglePos = 7;

void setup() {
  for (int i = 1; i < 120; i++;) {
    variableNames[i] = readEE(variableNames[i] + 'Pos');
  }

C ++/Arduino yordamida bu mumkinmi?

1
EEPROM o'zgaruvchini RAMga nusxalash (ya'ni, belgilar majmuasiga). Keyin so'zni oxirigacha qo'shish uchun strcat dan foydalaning. Ish tugagan so'zlar uchun etarli joy va 0x00 baytni bekor qilish.
qo'shib qo'ydi muallif Nick Gammon, manba

2 javoblar

Bunga oddiy preprocessor so'l bilan erishish mumkin:

#define readEE(VAR) VAR = readEEPROM(AT24C32_ADDRESS, 1, VAR ## Pos)

Siz undan keyin foydalanishingiz mumkin:

readEE(foo);

va u kengaytiriladi:

foo = readEEPROM(AT24C32_ADDRESS, 1, fooPos);

Makrosdagi ## operatori har ikkala tomonni ham kengaytiradi (VAR va POS) va keyin natijalarni birga birlashtiradi. VAR'nin o'zi makro (makroyu chaqirganingizda nima bo'lishidan qat'i nazar) bu qiymat bilan almashtiriladi, lekin Pos, chunki u makro emas, balki faqat Pos sifatida qoladi. Shunday qilib, "Pos" so'zi bilan birlashtirilgan o'zgarmaydigan nomingiz bilan yakunlanasiz.

Shuni eslatib o'tish joizki, bu o'zgaruvchining nomini o'zgartirilgan nomlar qatorida ishlatish mumkin emas - chunki o'zgartirilgan ismlar faqat olingan kodda emas, balki manba kodida mavjud, shuning uchun kod o'zgarmaydigan nomlar bilan hech narsa qila olmaysiz tuzilgan. Shuning uchun ishni bajarish uchun oldindan tayyorlovchidan foydalaning.

Ha, bu 120 o'zgaruvchining 120 ta kodini yozish kerakligini anglatadi, lekin ular faqat readEE (varame); ga qisqartiriladi.

Biroq, yaxshiroq yechim, yoki Mikoilning strukturasini qo'llash yoki oddiygina qatorni ishlatish va nomlarning kontseptsiyasi haqida boshqacha fikr yuritish:

uint8_t data[120];
for (int i = 0; i < 120; i++) {
    data[i] = readEEPROM(AT24C32_ADDRESS, 1, i);
);

Shuning uchun endi barcha o'zgaruvchan qadriyatlaringiz data [] qatoriga kiradi va siz faqat o'zingizning dasturda qanday qiymati borligini bilishingiz kerak - va siz har bir pozitsiyaning nomini preprocessor makrolar:

#define FAN_SPEED 12
#define N1_TOGGLE 95
#define LEDS_TOGGLE 7

Keyin raqamlarni o'rnida ushbu makrolardan foydalaning:

Serial.println(data[FAN_SPEED]);

Shu bilan bir qatorda makroları "niqoblarini" o'zgarmaydigan nomlari uchun foydalanishingiz mumkin:

#define fanSpeed data[12]
#define n1Toggle data[95]
#define ledsToggle data[7]

Hech bo'lmasa bir narsani ko'rgan bo'lardingiz: bu erda hech narsa kodingizni qisqartiradi, faqat biroz atrofdagi narsalarni olib keladi. Buni ko'rib chiqaylik - sizda 120 ta joyda saqlanadigan 120 ta o'zgaruvchi mavjud. Nima bo'lishidan qat'i nazar, siz hali ham ushbu o'zgaruvchilarga va ular joylashgan joylarga 120 ta ko'rsatgichga ega bo'lishingiz kerak. Siz haqiqatan ham qila oladigan narsalar sizning kodingizga qaraydigan biror kishi nima sodir bo'layotganini tushunish uchun eng ko'p o'qilishi mumkin bo'lgan usulni tanlashdir. Nima bo'lishidan qat'i nazar, sizga yozib qo'yadigan yoki sozlash uchun o'zgaruvchan yoki o'zgarmaydigan nomlarning uzun ro'yxati mavjud.

3
qo'shib qo'ydi
Qisqartirilgan "katta rasm" uchun juda minnatdormiz. Barcha usullarni o'rganishni yaxshi ko'raman. Menimcha, dastlabki protsessor dastlabki protsessor so'rovi bilan bo'ladi, chunki bu o'zgaruvchilardan yozilishning yo'lini o'zgartirmasdan kodni qisqartiradi/soddalashtiradi (mening asosiy maqsadim bo'lgan). Argumentlar saqlanadigan usulni o'zgartirganimda, yuzlab qatorlarni o'zgartirish kerak bo'lar edi, agar men kelajakda vaqt/xohishim bo'lsa, tajriba o'tkazishim mumkin.
qo'shib qo'ydi muallif Alex Rigos, manba
Men kodni oldingi protsessor echimini qo'shib qo'ydim va u ajoyib ishlamasdan ishladi. Bu muammoning eng ideal echimidir. Rahmat.
qo'shib qo'ydi muallif Alex Rigos, manba
Dastlabki protsessor echimi chindan ham yaxshi - bu haqda o'ylamagan edim :).
qo'shib qo'ydi muallif Mikael Patel, manba
variableNames[i] = readEE(variableNames[i] + 'Pos');

Bu C ++/Arduino yordamida amalga oshirilishi mumkinmi?

Yo'q! Juda oz dasturlash tillari bu ko'p ish vaqti ma'lumotlarini talab qiladi.

Keling, sizni qayta ko'rib chiqaylik; EEPROM dan katta hajmdagi bir qator o'zgaruvchini yuklang. C/C ++ va AVR kutubxonasida bu yordam beradigan qanday mexanizmlar mavjud?

Bu erda "yagona lineykaga" ega bo'lgan juda oddiy echim; eeprom_read_block ().

struct var_t {
  byte fanSpeed, nl1Toggle, ledsToggle;
};
var_t var;
const void* pos = ...;
eeprom_read_block(&var, pos, sizeof(var));

Shubhasiz, var_t va var juda yaxshi nomlar emas (va siz yaxshi narsalar bilan kelishingiz kerak) va bu ichki EEPROM uchun I2C EEPROM.

Cheers!

BW: Siz AT24CXXX kutubxonasidan foydalanmoqdasiz? Chunki bu g'alati ko'rinadi.

 uint8_t readEE(uint8_t entry) {
   readEEPROM(AT24C32_ADDRESS, 1, entry);
 }

Orqaga qaytish va boshqalar.

3
qo'shib qo'ydi
Javobingiz uchun tashakkur! Bu narsalar men uchun biroz murakkab, shuning uchun men aniqroq tushunish uchun avval o'rganmoqchiman (ko'proq o'rganishim kerak bo'lgan @Nick Gammonning fikrlari uchun ham xuddi shunday). AT24CXXX DS3231 RTC kartochkasida, va shuning uchun kamroq tarqalgan DS3231 kutubxonalaridan biriga murojaat qilish kerak, deb o'ylayman, bu bilan Due bilan ishlaydigan (ATmegas bilan ishlaydigan narsalarni topish oson). Men foydalanadigan kod bu erda joylashgan: github.com/kriswiner/DS3231RTC . O'ylaymanki, men bu ishni bajarish uchun hali biror o'zgartirish kiritishga majbur bo'ldim, ammo aniq esimda yo'q.
qo'shib qo'ydi muallif Alex Rigos, manba