Это что за поток сознания? О чём этом? То, что ты неоправданно и не к месту используешь довольно сложный и дорогостоящий механизм, это понятно, а вот смысла предыдущего поста не понял.
Слушь, Квон, ты меня убедил! Принимай в свою секту лямбдафилов!
Как опытный человек, зацени мою попытку. Это обычный блинк на 13-ом пине с периодом в одну секунду. но написан не по-лоховски, а продвинуто - с лямбдами.
Вопрос не в работоспособности - работает на uno/nano отлично (компилировал в IDE 1.8.9). Вопрос в том, достаточно ли лямбдануто?. Или можно полямбданутее?
Открой для себя рефакторинг - непременный атрибут профессиональной жизни программиста Когда я слышу "легче переписать" - хочется дать пинка говорящему. Хотя да - у самого возникают иногда такие мысли, в запале, но, как правило - подумавши, понимаешь, что нет - не легче переписать, надо именно рефакторить.
С одной стороны понятно. Если в коде много строк, то переписывать все долго, трудно и бесплатно. Лучше переписать часть и даже часть части. С другой стороны здесь на форуме открывается много тем, где надо провести "рефактринг"=поправить чуть чуть код, а то код не работает . Хотя всей душой понимаешь, что ТС его код ( а скорее и не его) надо отправить на **й, потому что переписывать надо все а потом еще учить его почему и зачем это надо. Вот и выходит что рефакторинг это еще одно модное словечко из лексикона эффективных менеджеров от программирования. :))
ПС: ЕвгенийП Вы что решились чистить эту тему? Я что нарушил какие-то неписаные правила .!!!
Мне вот интересно: переписывание блинка с дилей на миллис - это рефакторинг или нет?
Сложно сказать без контекста. Если это улучшает структурную организацию кода, повышает его читабельность и документированность, попутно выявляет ошибки - то да, это рефакторинг, и будет рефакторингом, если даже переписать с делай на делай. В противном случае, пмсм - это просто переписывание кода.
С одной стороны понятно. Если в коде много строк, то переписывать все долго, трудно и бесплатно. Лучше переписать часть и даже часть части. С другой стороны здесь на форуме открывается много тем, где надо провести "рефактринг"=поправить чуть чуть код, а то код не работает . Хотя всей душой понимаешь, что ТС его код ( а скорее и не его) надо отправить на **й, потому что переписывать надо все а потом еще учить его почему и зачем это надо. Вот и выходит что рефакторинг это еще одно модное словечко из лексикона эффективных менеджеров от программирования. :))
ПС: ЕвгенийП Вы что решились чистить эту тему? Я что нарушил какие-то неписаные правила .!!!
Мне вот интересно: переписывание блинка с дилей на миллис - это рефакторинг или нет?
qwone пишет:
Если вам за это заплатят, то скорее всего да. А если на шару то скорее нет. А так музыкальная пауза
DIYMan пишет:
Сложно сказать без контекста. Если это улучшает структурную организацию кода, повышает его читабельность и документированность, попутно выявляет ошибки - то да, это рефакторинг, и будет рефакторингом, если даже переписать с делай на делай. В противном случае, пмсм - это просто переписывание кода.
Лично я в большей степени согласен с DIYMan.
Кстати, музыкальная пауза - фиговенькая. И больше половины дефайнов можно было бы убрать.
А еще, коль скоро мы используем только математически точные длительности, их в дефайны можно было добавить. Дабы легко менять темп.
А если я начал переписывать код, сделал его понятней, убавил багов, но при етом, мать его ети, увеличил на 1кб - это рефакторинг или перевод добра на г....?
А если я начал переписывать код, сделал его понятней, убавил багов, но при етом, мать его ети, увеличил на 1кб - это рефакторинг или перевод добра на г....?
А если я начал переписывать код, сделал его понятней, убавил багов, но при етом, мать его ети, увеличил на 1кб - это рефакторинг или перевод добра на г....?
Я надеюсь, код не для Ардуино? Тогда мегабайтом больше, мегабайтом меньше, какая разница.
А если серьезно, то убранные баги вполне стоят килобайта. Разумеется, если предыдущий килобайт не был последним.
Может я чего не заметил, но мне кажется. что строки №№ 9-11 можно удалить и ничего не изменится. Я чего-то недопонял?
Да именно НЕ допоняли и именно НЕ заметили.
ЕвгенийП пишет:
Этот текст НЕ является универсальной библиотекой, НЕ поддерживается и НЕ сопровожадется. Это домашняя вещь для домашнего использования. Я просто увидел, что она как-то расползлась и даже появилась у нас в одном из проектов в соответсвующем разделе. Потому и решил выложить изменения, о чём уже жалею.
В любом случае, я не консультирую по этому коду и не помогаю решать связанные с ним вопросы. Сейчас сделаю исключение, но впредь, имейте в виду.
#8 Так я тоже сделаю исключение. 1- код сырой и больше нужен для отработки механизмов работы 2- если не сделаешь как получилось , не поймешь что можно лучше 3- у той микросхемы есть большой прикол - работаем побайтно или по странично (32 байта). Если делаем постранично , то нужна задержка 0,01 секунда 4- мне было интересно совместить шаблон и часные случаи.
ПС: учитель это не тот кто учит, а у того кого вы учитесь. Код здесь это просто личная записная книжка выложенная для публичного просмотра. Если кому интересно учится на моем коде я не возражаю. Но меня учить не надо. Я прекрасно вижу свои ошибки. А если не увижу сейчас , то увижу потом,для чего я и открыл эту тему.
Спасибо. Долго не мог понять зачем Вы это выкладываете. Пожалуй поучусь у Вас тоже .. в смысле попробую понять где и как смогу применить этот подход. Надеюсь не возражаете? Критиковать и комментировать - не буду, обещаю.
И в мыслях не было. Я лишь спросил то, чего не понял и совершенно не понимаю Вашей агрессии в ответ.
Если это личная записаня книжка, то почему она на публичном ресурсе? А если публичная, то может Вам как-то поадекватнее реагировать на вопросы, которые Вам задают? Впрочем, это, конечно, не моё дело.
Если это личная записаня книжка, то почему она на публичном ресурсе? А если публичная, то может Вам как-то поадекватнее реагировать на вопросы, которые Вам задают? Впрочем, это, конечно, не моё дело.
Ответов не будет. Так как только этим и придется заниматься, а потом еще "в говне" окажешься. Я же все же питаюсь научиться программировать серьезные программы , а так же пройти всю цепочку развития программирования самостоятельно.
Пух, не забывай, что буфер у Wire 32 байта, и когда ты страницу хочешь записать, адрес ячейки куда писать займет в буфере 2 байта, и записать потом ты можешь еще 30, а 2 последних в ROM не попадут.
Код твой я не читал, я просто спрашиваю, знаешь ли ты абэтом
Воспользуйтесь этим драйвером I2C, тут буфер внешний. Сколько надо - столько и заявите и даже статически:
/**
* Работа с TWI (I2C, 2-Wire) интерфейсом через аппаратные прерывания.
*
* ! Аппаратно не бывает одновременно режима Master-RX и Slave-RX - поэтому тут используется ОДИН буфер.
* ! Нет никаких "проверок", настройка глобалов - обязательна до каждого запуска автомата:
* Master-Transmitter: twiMT_Ptr, twiMT_Count -- откуда и сколько байт свистеть;
* Master-Receiver: twiRX_Ptr, twiRX_Count, twiMasterReader -- куда и сколько принять и (опц.)что потом сделать;
* Slave-Receiver: twiRX_Ptr, twiRX_Count, twiSlaveReader -- куда и сколько принять и (обяз.)что сделать;
* Slave-Transmitter: twiST_Ptr, twiST_Count, twiSlaveWriter -- откуда и сколько отдать и (обяз.)что потом сделать;
*
* Особенности и отличия от типовых разработок (собрано многое вместе):
* 1. Возможность одновременной работы как в режиме Master так и в режиме Slave;
* 2. Внешняя буферизация данных при необходимости. Размер памяти определяется вашей программой, а не тут;
* 3. Возможность ведения статистики - управляется константами компиляции;
* 4. Произвольная настройка скорости работы интерфейса от 490гц до 1Мгц с авто вычислением прескалера и регистра скорости
* 5. Возможность уменьшенной комплиции, если не требуются все режимы сразу.
*
* Константы компиляции #define:
* #define TWI_ON 1 // если не определено, то обработчик прерывания I2C останется, но практически ПУСТОЙ!
* Перед включением этого файла надо определить TWI_ON значениями:
*
* #define TWI_ON 1 // Master-Transmitter only: компилировать как режим Мастера-передатчика ,ISR(TWI)=190 байт
* #define TWI_ON 2 // Master-Receiver only: компилировать как режим Мастер-приемник ,ISR(TWI)=224 байт
* #define TWI_ON 4 // Slave-Receiver only: компилировать как режим Ожидающий получатель ,ISR(TWI)=202 байт
* #define TWI_ON 8 // Slave-Transmitter only: компилировать как режим Отправитель по запросу ,ISR(TWI)=188 байт
*
* @TODO: #define TWI_ON 16 // + Logging: Включить в компиляцию логирование работы интерфейса.
*
* !!! Допускается компиляция нескольких режимов одновременно:
* #define TWI_ON (1+2+4+8) // Включить в компиляцию ВСЕ режимы. ,ISR(TWI)=424 байт.
*
* @author Arhat109-20160402. arhat109@mail.ru
* @license:
* 1. This is a free software for any using and distributing without any warranties.
* 2. You should keep author tag with any changes. May be with adding.
* Это свободное ПО для любого использования без каких-либо гарантий и претензий.
* Требуется сохранять тег @author при любых изменениях. Можете дописать свой.
*/
#ifndef _ARHAT_TWI_H_
#define _ARHAT_TWI_H_ 1
#include "arhat.h"
// If not defined - use as Master Transmitter only!
// Если нет ничего, то только управляющий мастер!
#ifndef TWI_ON
# define TWI_ON TWI_MASTER_TX
#endif // TWI_ON
// ------------ All states TWI status register AND twiState: ------------- //
// Misc
#define TWI_ERROR 0x00 // Misc: illegal start or stop condition
#define TWI_NO_INFO 0xF8 // Misc: no state information available
// I am Master
#define TWI_START 0x08 // start condition transmitted
#define TWI_REP_START 0x10 // repeated start condition transmitted
#define TWI_MTR_ARB_LOST 0x38 // arbitration lost in SLA+W or data
// Master Transmitter
#define TWI_MT_SLA_ACK 0x18 // address: SLA+W transmitted, ACK received
#define TWI_MT_SLA_NACK 0x20 // address: SLA+W transmitted, NACK received
#define TWI_MT_DATA_ACK 0x28 // data: transmitted, ACK received
#define TWI_MT_DATA_NACK 0x30 // data: transmitted, NACK received
// Master Receiver
#define TWI_MR_SLA_ACK 0x40 // address: SLA+R transmitted, ACK received
#define TWI_MR_SLA_NACK 0x48 // address: SLA+R transmitted, NACK received
#define TWI_MR_DATA_ACK 0x50 // data: received, ACK returned
#define TWI_MR_DATA_NACK 0x58 // data: received, NACK returned
// I am Slave
// Slave Receiver
#define TWI_SR_SLA_ACK 0x60 // address: SLA+W received, ACK returned
#define TWI_SR_ARB_LOST_SLA_ACK 0x68 // arbitration lost in SLA+RW, SLA+W received, ACK returned
#define TWI_SR_GCALL_ACK 0x70 // general call received, ACK returned
#define TWI_SR_ARB_LOST_GCALL_ACK 0x78 // arbitration lost in SLA+RW, general call received, ACK returned
#define TWI_SR_DATA_ACK 0x80 // data: received, ACK returned
#define TWI_SR_DATA_NACK 0x88 // data: received, NACK returned
#define TWI_SR_GCALL_DATA_ACK 0x90 // general call data received, ACK returned
#define TWI_SR_GCALL_DATA_NACK 0x98 // general call data received, NACK returned
#define TWI_SR_STOP 0xA0 // stop or repeated start condition received while selected
// Slave Transmitter
#define TWI_ST_SLA_ACK 0xA8 // address: SLA+R received, ACK returned
#define TWI_ST_ARB_LOST_SLA_ACK 0xB0 // arbitration lost in SLA+RW, SLA+R received, ACK returned
#define TWI_ST_DATA_ACK 0xB8 // data: transmitted, ACK received
#define TWI_ST_DATA_NACK 0xC0 // data: transmitted, NACK received
#define TWI_ST_LAST_DATA 0xC8 // last data byte transmitted, ACK received
// ------------ Macros for TWI ------------- //
#define TWI_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3)) // Two LSB are prescaler bits
#define TWI_STATUS (TWSR & TWI_STATUS_MASK) // Get status from TWSR
#define TWI_READ 1 // for SLA+R address
#define TWI_WRITE 0 // SLA+W address
#define TWI_ACK 1
#define TWI_NACK 0
#define twiOn() (PRR0 &= ~_BV(7)) // =0: TWI power is On (default on power!)
#define twiOff() (PRR0 |= _BV(7)) // =1: TWI power is Off
/**
* Set twi bit rate and prescaler: _twbr:[0..255], _twsr:[0..3]
* ------------------------------------------------------------
* _twsr = 3: scl freq. = [ 490 .. 111_111] hz
* _twsr = 2: scl freq. = [ 1_960 .. 333_333] hz
* _twsr = 1: scl freq. = [ 7_782 .. 666_667] hz
* _twsr = 0: scl freq. = [30_418 .. 888_889] hz
* IF _twbr = 0: frequency equal 1 Mhz with any _twsr!
*
* @example twiSetRate(72,0) : use 100_000hz standart mode
* @example twiSetRate(12,0) : use 400_000hz standart mode
* @example twiSetRate(0,0) : use 1 Mhz mode
*/
#define twiSetRate(_twbr, _twsr) \
{ \
_SFR_BYTE(TWSR) = (uint8_t)(_twsr); \
TWBR = (uint8_t)(_twbr); \
}
/**
* Макросы управления автоматом TWI: последняя команда везде - запись в TWCR
*
* @param bool ack -- есть ли режимы Slave, надо ли слушать шину?
*
* twiStart() -- включаем, разрешаем, сброс прерывание(запуск КА) и выставляем старт на шину.
* twiReply() -- оно же, только без старта
* twiReleaseBus() -- включаем, сброс прерывание(запуск КА), а вот прерывание разрешаем только если есть Slave
* twiStop() -- оно же, только ещё и отправляем "стоп" в шину и ждем исполнения.
*/
#define twiStart(ack) (_BV(TWEN)|_BV(TWINT)|_BV(TWIE)|_BV(TWSTA)|((ack)?_BV(TWEA):0))
#define twiReply(ack) (_BV(TWEN)|_BV(TWINT)|_BV(TWIE)|((ack)? _BV(TWEA):0))
#define twiReleaseBus(ack) (_BV(TWEN)|_BV(TWINT)|((ack)? _BV(TWEA)|_BV(TWIE):0))
#define twiSetAddress(address, isGcall) (TWAR = (uint8_t)(((address) << 1)|((isGcall)&0x01)))
#define twiSetMaskAddress(mask) (TWAMR = (uint8_t)(mask))
#define twiStop(ack) \
{ \
TWCR = _BV(TWSTO)|twiReleaseBus(ack); \
while(TWCR & _BV(TWSTO)); \
twiMode |= TWI_READY; \
}
#ifdef __cplusplus
extern "C" {
#endif
// ------------ TWI internal variables ------------- //
enum TwiModes {
TWI_IS_SLAVE = 1 // have I slave mode too?
,TWI_SEND_STOP = 2 // is need send stop when Master is ending?
,TWI_READY = 4 // previous work is ended
};
volatile uint8_t twiMode;
volatile uint8_t twiState; // state TWI automat
volatile uint8_t twiSLARW; // address for send to (SLARW)
volatile uint8_t twiMT_Count; // остаток байт для передачи мастеров
volatile uint8_t * twiMT_Ptr; // указатель текущего байта внешнего буфера передачи мастером
volatile uint8_t twiRX_Count; // остаток байт для приема мастером/слейвом
volatile uint8_t * twiRX_Ptr; // указатель текущего байта внешнего буфера приема мастером/слейвом
volatile uint8_t twiST_Count; // остаток байт для передачи слейвом
volatile uint8_t * twiST_Ptr; // указатель текущего байта внешнего буфера передачи слейвом
void (* twiHookRestart)(void) = 0; // указатель на функцию перезапуска мастера без освобождения шины (TWI_SEND_STOP)
void (* twiMasterReader)(void) = 0; // указатель на функцию "Master принял данные, куда их?"
void (* twiSlaveReader)(void) = 0; // указатель на функцию "Slave принял данные, куда их?"
void (* twiSlaveWriter)(void) = 0; // указатель на функцию "Slave всё отправил, что дальше?"
/*
#if defined(TWI_ON) && (TWI_ON & TWI_LOG_ON)
typedef struct {
uint16_t starts,restarts,stops,losts,noslarw,mtx,mrx,srx,grx,stx;
} TwiStat;
#define ptrTwiStat(ptr) ((TWI_Stat *)(ptr))
static volatile TwiStat twiStatistic;
#endif // TWI_ON::TWI_LOG_ON
*/
// ------------ TWI functions ------------- //
/**
* Autocalculate and set twi prescaler and bit rate
* 1Mhz .. 30.418khz : TWSR=0!
* 30.42khz .. 7.782khz : TWSR=1
* 7.782khz .. 1.960khz : TWSR=2
* 1/960khz .. 0.490khz : TWSR=3
*/
void twiSpeed(uint32_t freq)
{
uint16_t bitRate = (F_CPU / freq) - 16;
uint8_t bitMul = 0;
while( (bitRate > 511) && (bitMul < 3) ){
bitRate /= 4; bitRate += 1; bitMul++;
}
bitRate /= 2;
if( bitRate > 255 ) return;
twiSetRate(bitRate, bitMul);
}
/**
* for Arduino setup() as Master or Slave or Both modes
* freq:[490 .. 1 000 000], mode:[0,TWI_IS_SLAVE]
*/
void twiSetup(uint32_t freq, uint8_t mode)
{
pinOut(I2C_SDA, HIGH); // internal pullup is ON.
pinOut(I2C_SCL, HIGH);
twiSpeed(freq); // set bitrate and prescaler for frequency
twiMode = mode;
TWCR = _BV(TWEN)|_BV(TWIE)|((mode&TWI_IS_SLAVE)?_BV(TWEA):0); // module, acks, and interrupt is ON
}
/**
* for ISR(TWI): control restart conditions in all modes:
* ! if only 1 mode -- this is a MACRO with next RETURN into ISR, else - function !
*
* 1. Освобождать шину, или надо ещё (напр. прием после передачи)?
* да: Сеанс завершен. Ждем прямо тут прохождения стопа! Выходим из обработчика тут!
* нет, рестарт:
* .. есть Хук? процедура подготовки след. посылки: указатели, размеры, адрес, режим..
* .. а нет Хука! Типовой режим "чтение после записи"
* в любом случае отправляем restart
*
*/
#if ((TWI_ON & 0x0F)!=1) && ((TWI_ON & 0x0F)!=2) && ((TWI_ON & 0x0F)!=4) && ((TWI_ON & 0x0F)!=8)
void twiSendStop(uint8_t _md)
{
if (_md & TWI_SEND_STOP)
{
TWCR = _BV(TWSTO)|twiReleaseBus(_md & TWI_IS_SLAVE);
while(TWCR & _BV(TWSTO));
twiMode |= TWI_READY;
}else{
if( twiHookRestart ){
twiHookRestart();
} else {
twiSLARW |= TWI_READ;
}
TWCR = twiStart(_md & TWI_IS_SLAVE);
}
}
#else
#define twiSendStop(_md) \
{ \
TWCR = _BV(TWSTO)|twiReleaseBus((_md) & TWI_IS_SLAVE); \
while(TWCR & _BV(TWSTO)); \
twiMode |= TWI_READY; \
}
#endif
/**
* ISR for TWI interface: realised master and slave modes
* ------------------------------------------------------
*/
ISR(TWI_vect)
{
uint8_t _cr = twiReply(0);
uint8_t _md = twiMode;
uint8_t _st = twiState=TWI_STATUS;
#if defined(TWI_ON) && ((TWI_ON & TWI_IS_SLAVE_TX)||(TWI_ON & TWI_IS_SLAVE_RX))
if( _st >= TWI_SR_SLA_ACK )
{
#if (TWI_ON & TWI_IS_SLAVE_TX)
if( (_st == TWI_ST_DATA_NACK) || (_st == TWI_ST_LAST_DATA) )
{
// ST: Был последний байт, мастер наелся ..
// ST: Был наш последний байт: предупреждали мастера twiReply(NACK)
twiSlaveWriter(); // Хук - обязателен! Дальше нечего передавать..
_md=twiMode; // возможно изменение режимов в хуке!
twiSendStop(_md); return;
}else{
if( (_st == TWI_ST_ARB_LOST_SLA_ACK) || (_st == TWI_ST_SLA_ACK || _st == TWI_ST_DATA_ACK) )
{
// ST: Моего мастера заткнули и просят данные ..
// ST: Мой адрес, начинаем ..
// ST: Отправлено успешно, продолжаем ..
TWDR = *twiST_Ptr++;
_cr = twiReply(--twiST_Count);
}else{
#endif // TWI_ON::TWI_IS_SLAVE_TX
#if (TWI_ON & TWI_IS_SLAVE_RX)
if( (_st == TWI_SR_GCALL_DATA_NACK) || (_st == TWI_SR_DATA_NACK) || (_st == TWI_SR_STOP) )
{
if( (_st == TWI_SR_GCALL_DATA_NACK) || (_st == TWI_SR_DATA_NACK) )
{
// SR: УПС. GCall - туда же.
// SR: УПС. Получен байт, мастеру уже был отправлен NACK
*twiRX_Ptr = TWDR;
}
// SR: Обнаружен stop или restart в процессе приема .. это всё?
twiSlaveReader(); // Хук обязателен! это последний, дальше некуда складывать!
_md=twiMode; // возможно изменение режимов в хуке!
twiSendStop(_md); return;
}else{
if( (_st == TWI_SR_GCALL_DATA_ACK) || (_st == TWI_SR_DATA_ACK) )
{
// SR: пришел байт всем - аналогично
// SR: пришел байт, можно ещё принять
*(twiRX_Ptr++) = TWDR;
}
// TWI_SR_ARB_LOST_SLA_ACK SR: Мастер потерял шину: нет данных ..
// TWI_SR_ARB_LOST_GCALL_ACK SR: Вызов всем потерял шину (как это?) --""--
// TWI_SR_SLA_ACK SR: Адрес принят, ещё только ждем данные
// TWI_SR_GCALL_ACK SR: Вызов всем принят оно же
_cr = twiReply(--twiRX_Count); // .. приняли байт и отправляем NACK если осталось 1 место.
}
#endif // TWI_ON::TWI_IS_SLAVE_RX
#if (TWI_ON & TWI_IS_SLAVE_TX)
}
}
#endif // TWI_ON::TWI_IS_SLAVE_TX
}else{
#endif // TWI_ON::TWI_SLAVE..
#if defined(TWI_ON) && (TWI_ON & TWI_MASTER_TX)
// Master Transmiter or Reciever modes
if( (_st == TWI_START) || (_st == TWI_REP_START) )
{
// MT,MR:: Прошла отправка стартовой посылки
// MT,MR:: Прошла отправка повторного старта
TWDR = twiSLARW;
_cr = twiReply(_md & TWI_IS_SLAVE);
}else{
if( (_st == TWI_MT_SLA_NACK) || (_st == TWI_MT_DATA_NACK) )
{
// TWI_MT_DATA_NACK MT:: Упс. data NACK: Получатель не хотит?
// TWI_MT_SLA_NACK MT:: Упс. Получатель NACK .. не откликается зараза.
twiSendStop(_md); return;
}
if( (_st == TWI_MT_SLA_ACK) || (_st == TWI_MT_DATA_ACK) )
{
// MT: Адрес получателя отправлен успешно, начинаем
// MT: Байт данных отправлен, продолжаем
if( twiMT_Count-- ){
TWDR = *twiMT_Ptr++;
_cr = twiReply(_md & TWI_IS_SLAVE);
}else{
twiSendStop(_md); return;
}
}else{
#endif // TWI_ON::TWI_MASTER_TX
#if defined(TWI_ON) && (TWI_ON & TWI_MASTER_RX)
if( _st == TWI_MTR_ARB_LOST )
{
// MT,MR: Упс. Мастер потерял шину: освобождаем и ждем/слушаем.
_md |= TWI_READY;
_cr = twiReleaseBus(_md & TWI_IS_SLAVE);
}else{
if( (_st == TWI_MR_DATA_ACK) || (_st == TWI_MR_SLA_ACK) )
{
if( _st == TWI_MR_DATA_ACK ){
// MR: байт принят, ACK отправлен
*(twiRX_Ptr++) = TWDR;
}
// MR: Отправитель найден, начинаем прием
_cr = twiReply( --twiRX_Count ); // .. Можно ещё принять? Или Отправителю - NACK
}else{
if( _st == TWI_ERROR ) return;
if( _st == TWI_MR_DATA_NACK )
{
// MR: Упс. Получен последний байт дальше принимать некуда.
*twiRX_Ptr = TWDR;
if( twiMasterReader ) twiMasterReader();
// goto TWI_RET_HOOK;
_md=twiMode; // возможно изменение режимов в хуке!
}
// All other Master states: stop/restart if need
// TWI_MR_SLA_NACK MR:: Упс. Отправитель NACK .. не откликается зараза.
twiSendStop(_md); return;
}
}
#endif // TWI_ON::TWI_MASTER_RX
#if defined(TWI_ON) && (TWI_ON&TWI_MASTER_TX)
}
}
#endif // TWI_ON::TWI_MASTER_TX
#if defined(TWI_ON) && ((TWI_ON & TWI_IS_SLAVE_TX)||(TWI_ON & TWI_IS_SLAVE_RX))
}
#endif // TWI_SLAVE_ON
twiMode = _md;
TWCR = _cr;
} //end ISR()
// ------------------------- (PROTECTED) ------------------------- //
// Внутренние методы интерфейса, могут пригодится для создания внешних уровней работы с I2C //
// ---------------------------------------------------------------------------------------- //
/**
* INTERNAL:: Простая передача. Запись адреса собеседника и запуск автомата TWI
*
* @see twiWrite(), twiRead()
*/
void _twiStartTo(uint8_t address)
{
twiSLARW = address; // Режим поставляется вместе с адресом!
twiMode |= TWI_SEND_STOP; // только 1 бит! Могли быть иные режимы..
TWCR = twiStart(twiMode & TWI_IS_SLAVE);
}
/**
* INTERNAL:: Передача с рестартом. Запись адреса собеседника и запуск автомата TWI
*
* @see twiWrite(), twiRead()
*/
void _twiStartRe(uint8_t address)
{
twiSLARW = address; // Режим поставляется вместе с адресом!
twiMode &= ~TWI_SEND_STOP; // только 1 бит! Могли быть иные режимы..
TWCR = twiStart(twiMode & TWI_IS_SLAVE);
}
#define _twiWaitReady() {while(!(TWI_READY & twiMode)); twiMode &= ~TWI_READY;}
#define _twiMT_Buffer(data, length) (twiMT_Ptr=(volatile uint8_t *)(data), twiMT_Count=(volatile uint8_t)(length))
#define _twiRX_Buffer(data, length) (twiRX_Ptr=(volatile uint8_t *)(data), twiRX_Count=(volatile uint8_t)(length))
#define _twiST_Buffer(data, length) (twiST_Ptr=(volatile uint8_t *)(data), twiST_Count=(volatile uint8_t)(length))
// ------------------------- PUBLIC ------------------------- //
// ---------------------------------------------------------------------------------------- //
/**
* Master-TX:: Передача length байт по адресу получателя. Только запуск!
*/
void twiWrite(uint8_t address, const uint8_t * data, uint8_t length)
{
_twiWaitReady(); // Ждем завершения предыдущей работы
_twiMT_Buffer(data, length);
_twiStartTo( (address<<1) | TWI_WRITE ); // Режим передачи!
}
/**
* MASTER-RX:: Прием length байт из адреса отправителя. Только запуск!
*/
void twiRead(uint8_t address, uint8_t * data, uint8_t length)
{
_twiWaitReady(); // Ждем завершения предыдущей работы
_twiRX_Buffer(data, length);
_twiStartTo( (address<<1) | TWI_READ ); // Режим приема данных!
}
/**
* Master Read-after-Write:: Чтение данных после отправки команды. Только запуск.
* !!! Не совместимо с Slave Receive Mode - буфер приема общий !!!
*/
void twiRAW(uint8_t address // адрес устройства
, uint8_t* command, uint8_t clength // команда и её длина
, uint8_t* data, uint8_t dlength // буфер приема данных и его длина
){
_twiWaitReady(); // Ждем завершения предыдущей работы
_twiMT_Buffer(command, clength);
_twiRX_Buffer(data, dlength);
twiHookRestart = 0; // типовой переход на чтение этого же Slave
twiMode |= TWI_SEND_STOP; // рестарт после отправки команды
twiSLARW = (address<<1 | TWI_WRITE); // Сначала режим передачи!
TWCR = twiStart(twiMode & TWI_IS_SLAVE);
}
/**
* @example: Пример реализации обработчика "SLAVE отправил всё, что дальше?"
* для случая, когда текущий буфер можно отправлять повторно по следующему запросу
*
* !!! Использует доп. глобалы (должны быть определены в вашем скетче):
* uint8_t * stBuffer;
* uint8_t stBufferSize;
*//*
void twiSlaveRewriter(void)
{
_twiST_Buffer(stBuffer, stBufferSize); // просто перенастраиваем буфер на повторную передачу.
}
*/
#ifdef __cplusplus
}
#endif
#endif // _ARHAT_TWI_H_
Где-то был вариант с ведением логов передач и ошибок, если надо, поищу.
Строку 42 - можно удалить и в строках 212,213 заменить макрос pinOut() на digitalWrite() на ноги вашего I2C. Больше нигде этот хидер тут не нужен вроде бы..
Или так
typedef int(*pDo)(); //<-- создаем тип указатель на функцию byte fun(pDo Do) { return Do(); } //----------------------------------- void setup() { Serial.begin(9600); Serial.print( fun( [] { return 5;} //< внутри функции объявляем новую лямда функцию ) ); } void loop() { }Это что за поток сознания? О чём этом? То, что ты неоправданно и не к месту используешь довольно сложный и дорогостоящий механизм, это понятно, а вот смысла предыдущего поста не понял.
Слушь, Квон, ты меня убедил! Принимай в свою секту лямбдафилов!
Как опытный человек, зацени мою попытку. Это обычный блинк на 13-ом пине с периодом в одну секунду. но написан не по-лоховски, а продвинуто - с лямбдами.
Вопрос не в работоспособности - работает на uno/nano отлично (компилировал в IDE 1.8.9). Вопрос в том, достаточно ли лямбдануто?. Или можно полямбданутее?
Покритикуй в общем, пожалуйста.
// // Лямбда-блинк на пине LED_BUILTIN // constexpr auto pp = [] {return 500;}; // функция вычисления полупериода блинка void setup(void) { [] { [] { return pinMode;}() ( [] { return LED_BUILTIN; }(), [] { return OUTPUT; }() ); while(1) [] (void (*dw)(uint8_t, uint8_t)) { auto b = [] { return LED_BUILTIN; }(); dw( [&b] { return b; } (), ![] { return digitalRead; }() ([=] { return b; }()) ); [] { return delay; } () (pp()); } ([] { return digitalWrite; }()); } (); } void loop(void) {}Богу лямбд нужно больше лямбд)
А богу лямд?
Ну, я всё понимаю, но constexpr-то нафига здесь?
Да, шоб был!
А богу лямд?
Богу лямд - меньше метастабильности, и больше MTBF.
http://forum.amperka.ru/threads/%D0%90%D0%BD%D1%82%D0%B8-%D0%B4%D1%80%D0...
А теперь вопрос? Что такое рефакторить и с чем его едят. Гугл дал ответ такой https://iiba.ru/basic-principles-and-rules-of-refactoring/
А лямбданутее можно. Здесь я не вижу лямбд высших порядков, а можно было бы замутить.
С одной стороны понятно. Если в коде много строк, то переписывать все долго, трудно и бесплатно. Лучше переписать часть и даже часть части. С другой стороны здесь на форуме открывается много тем, где надо провести "рефактринг"=поправить чуть чуть код, а то код не работает . Хотя всей душой понимаешь, что ТС его код ( а скорее и не его) надо отправить на **й, потому что переписывать надо все а потом еще учить его почему и зачем это надо. Вот и выходит что рефакторинг это еще одно модное словечко из лексикона эффективных менеджеров от программирования. :))
ПС: ЕвгенийП Вы что решились чистить эту тему? Я что нарушил какие-то неписаные правила .!!!
Пральна пух! Так их!
ну, а чё за мои лябды? Не прокомментируешь?
ПС: ЕвгенийП Вы что решились чистить эту тему?
Я? Господь с Вами! И в мыслях не было. Удивило увидет здесь ответ на вопрос из амперки, вот и спросил. Нельзя? Я что-то нарушил?
Эта тема для сброса сюда очередного квонокода, а остальное просто лишнее.
project_AAA.ino
/*project_AAA*/ // Ардуино нано . Среда Arduino 1.8.0 // кнопки на землю и на пины 2,3,4 // реле 8,9,10,11 // lcd 1602_I2c на I2c #include "menu.h" #include "device.h" //--------------------------------------- void setup() { device_init(); menu_init(); } void loop() { device_run(); menu_run(); }device.h
/*device.h*/ #ifndef device_h #define device_h #include <Arduino.h> //-------------------------------------- class Cl_Relay { protected: byte pin; unsigned long past; bool state; void set( bool s) { digitalWrite(pin, state = s); } public: Cl_Relay(byte p): pin(p) {} void init() { pinMode(pin, OUTPUT); set(false); } void ON() { set(true); } void OFF() { set(false); } bool read() { return state; } }; template <> inline Cl_lcd1602_i2c & operator << (Cl_lcd1602_i2c &s, Cl_Relay obj) { if (obj.read()) s.print(" 0N"); else s.print("OFF"); return s; } //---------------------------------- const byte Relay_num = 4; Cl_Relay Relay[Relay_num] = { Cl_Relay(/*пин*/8), Cl_Relay(/*пин*/9), Cl_Relay(/*пин*/10), Cl_Relay(/*пин*/11) }; void device_init() { for (int i = 0; i < Relay_num; i++) Relay[i].init(); } void device_run() { } #endif // device.hlcd1602_I2C.h
/*lcd1602_I2C.h*/ #ifndef lcd1602_I2C_h #define lcd1602_I2C_h #include <Arduino.h> //------------- дисплей----------------------- #include <Wire.h> // команды #define LCD_CLEARDISPLAY 0x01 #define LCD_RETURNHOME 0x02 #define LCD_ENTRYMODESET 0x04 #define LCD_DISPLAYCONTROL 0x08 #define LCD_CURSORSHIFT 0x10 #define LCD_FUNCTIONSET 0x20 #define LCD_SETCGRAMADDR 0x40 #define LCD_SETDDRAMADDR 0x80 // флаги для режима ввода дисплея #define LCD_ENTRYRIGHT 0x00 #define LCD_ENTRYLEFT 0x02 #define LCD_ENTRYSHIFTINCREMENT 0x01 #define LCD_ENTRYSHIFTDECREMENT 0x00 // флаги для управления включением / выключением дисплея #define LCD_DISPLAYON 0x04 #define LCD_DISPLAYOFF 0x00 #define LCD_CURSORON 0x02 #define LCD_CURSOROFF 0x00 #define LCD_BLINKON 0x01 #define LCD_BLINKOFF 0x00 // флаги для отображения / сдвига курсора #define LCD_DISPLAYMOVE 0x08 #define LCD_CURSORMOVE 0x00 #define LCD_MOVERIGHT 0x04 #define LCD_MOVELEFT 0x00 // флаги для набора функций #define LCD_8BITMODE 0x10 #define LCD_4BITMODE 0x00 #define LCD_2LINE 0x08 #define LCD_1LINE 0x00 #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 // флаги для управления подсветкой #define LCD_lightON 0x08 #define LCD_lightOFF 0x00 #define En B00000100 // Бит разрешения #define Rw B00000010 // Чтение / запись бит #define Rs B00000001 // Бит выбора регистра class Cl_lcd1602_i2c : public Print { protected: uint8_t adr, posX, posY; uint8_t _lightONval; uint8_t _displayfunction; uint8_t _displaycontrol; uint8_t _displaymode; byte buffer[32]; public: Cl_lcd1602_i2c(uint8_t a): adr(a) {} void init() { Wire.begin(); write4bits(0x03 << 4); delayMicroseconds(4500); // ждем не меньше 4.1ms write4bits(0x03 << 4); delayMicroseconds(4500); // ждем не меньше 4.1ms write4bits(0x03 << 4); delayMicroseconds(150); write4bits(0x02 << 4); delay(50); _lightONval = LCD_lightOFF; expanderWrite(_lightONval); // сбросить расширение и выключить подсветку (бит 8 = 1) // режим работы дисплея 4-х битный интерфейс ,две строки,5х8 точек _displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS; command(LCD_FUNCTIONSET | _displayfunction); // режим контроля дисплей вкл, курсор не мигает,дисплей не мигает _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; command(LCD_DISPLAYCONTROL | _displaycontrol); // режим ввода текста в память-начинать слева с движением в право _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; command(LCD_ENTRYMODESET | _displaymode); clear(); lightON(); } // подсветку вкл/выкл void lightON(void) { _lightONval = LCD_lightON; expanderWrite(0); } void lightOFF(void) { _lightONval = LCD_lightOFF; expanderWrite(0); } // очистить буфер void clear() { for (byte i = 0; i < 32; i++ )buffer[i] = 0x20; posX = 0; posY = 0; } // отправить информацию из буфера на экран void show() { line(0); for (byte i = 0; i < 16; i++ )out(buffer[i]); line(1); for (byte i = 16; i < 32; i++ )out(buffer[i]); } void setCursor(byte x, byte y) { if (x > 16) x = 16; else posX = x; if (y > 2) x = 2; else posY = y; } private: /*внутрение функции*/ void line(byte l) { if (l == 0) command(LCD_SETDDRAMADDR | 0x00); else command(LCD_SETDDRAMADDR | 0x40); } inline void out(uint8_t value) { send(value, Rs); } inline size_t write(uint8_t value) { if (posX < 16 && posY < 2) { buffer[posY * 16 + posX] = value; posX++; } return 1; } /*команды низкоуровневого управления*/ inline void command(uint8_t value) { send(value, 0); } void send(uint8_t value, uint8_t mode) { uint8_t highnib = value & 0xf0; write4bits((highnib) | mode); uint8_t lownib = (value << 4) & 0xf0; write4bits((lownib) | mode); } void write4bits(uint8_t value) { expanderWrite(value); pulseEnable(value); } void expanderWrite(uint8_t _data) { Wire.beginTransmission(adr); Wire.write((int)(_data) | _lightONval); Wire.endTransmission(); } void pulseEnable(uint8_t _data) { expanderWrite(_data | En); // En high delayMicroseconds(1); // enable pulse must be >450ns expanderWrite(_data & ~En); // En low delayMicroseconds(50); // commands need > 37us to settle } }; typedef Cl_lcd1602_i2c& (*pDo1)(Cl_lcd1602_i2c&); template <typename T> inline Cl_lcd1602_i2c & operator << (Cl_lcd1602_i2c &s, T n) { s.print(n); return s; } template <> inline Cl_lcd1602_i2c & operator << (Cl_lcd1602_i2c &s, pDo1 Do) { Do(s); return s; } template <> inline Cl_lcd1602_i2c & operator << (Cl_lcd1602_i2c &s, byte n) { if (n < 10)s.print("0"); s.print(n); return s; } Cl_lcd1602_i2c& clear(Cl_lcd1602_i2c& s) { s.clear(); return s; } Cl_lcd1602_i2c& show(Cl_lcd1602_i2c& s) { s.show(); return s; } Cl_lcd1602_i2c lcd(0x27);//0x3F #endif // lcd1602_I2C.hmenu.h
/*menu.h*/ #ifndef menu_h #define menu_h #include <Arduino.h> #include "lcd1602_I2C.h" #include "device.h" //----------- кнопки ------------------------ typedef void (*pDo)(); class Cl_Btn { protected: byte pin; unsigned long past; bool state; void set(bool s) { past = millis(); state = s; if (s == true)Do(); } public: pDo Do = [] {}; Cl_Btn(byte p): pin(p) {} void init() { pinMode(pin, INPUT_PULLUP); set(false); } void run() { if (millis() - past >= 100) { switch (state) { case false : if (!digitalRead(pin)) set(true); break; case true : if (digitalRead(pin)) set(false); break; } } } }; Cl_Btn BtnL(/*пин*/2);// кнопка левая Cl_Btn BtnR(/*пин*/3);// кнопка правая Cl_Btn BtnS(/*пин*/4);// кнопка селект //----------- меню ---------------------------------- const byte scr0 = 0;// главный экран const byte scr1 = 10;// вкл/выкл реле 1 const byte scr2 = 20;// вкл/выкл реле 2 const byte scr3 = 30;// вкл/выкл реле 3 const byte scr4 = 40;// вкл/выкл реле 4 byte scr; unsigned long menu_past; void go(byte s) { scr = s; menu_past = millis(); lcd << clear; switch (s) { case scr0: { // главный экран lcd << F("1:") << Relay[0] << F(" 2:") << Relay[1]; lcd.setCursor(0, 1); lcd << F("3:") << Relay[2] << F(" 4:") << Relay[3]; BtnL.Do = [] {}; BtnR.Do = [] {go(scr1);}; BtnS.Do = [] {}; } break; case scr1: {// вкл/выкл реле 1 lcd << F("Re1:") << Relay[0]; BtnL.Do = [] {go(scr0);}; BtnR.Do = [] {go(scr2);}; BtnS.Do = [] { if (Relay[0].read()) Relay[0].OFF(); else Relay[0].ON(); go(scr1); }; } break; case scr2: {// вкл/выкл реле 2 lcd << F("Re2:") << Relay[1]; BtnL.Do = [] {go(scr1);}; BtnR.Do = [] {go(scr3);}; BtnS.Do = [] { if (Relay[1].read()) Relay[1].OFF(); else Relay[1].ON(); go(scr2); }; } break; case scr3: {// вкл/выкл реле 3 lcd << F("Re3:") << Relay[2]; BtnL.Do = [] {go(scr2);}; BtnR.Do = [] {go(scr4);}; BtnS.Do = [] { if (Relay[2].read()) Relay[2].OFF(); else Relay[2].ON(); go(scr3); }; } break; case scr4: {// вкл/выкл реле 4 lcd << F("Re4:") << Relay[3]; BtnL.Do = [] {go(scr3);}; BtnR.Do = [] {}; BtnS.Do = [] { if (Relay[3].read()) Relay[3].OFF(); else Relay[3].ON(); go(scr4); }; } break; } lcd << show; } void menu_init() { lcd.init(); BtnL.init(); BtnR.init(); BtnS.init(); go(scr0); } void menu_run() { BtnL.run(); BtnR.run(); BtnS.run(); if (scr == scr0 && millis() - menu_past >= 500) go(scr0); if (scr != scr0 && millis() - menu_past >= 5000) go(scr0); } #endif // menu.hМне вот интересно: переписывание блинка с дилей на миллис - это рефакторинг или нет?
Мне вот интересно: переписывание блинка с дилей на миллис - это рефакторинг или нет?
/**/ #define ntB0 31 #define ntC1 33 #define ntCS1 35 #define ntD1 37 #define ntDS1 39 #define ntE1 41 #define ntF1 44 #define ntFS1 46 #define ntG1 49 #define ntGS1 52 #define ntA1 55 #define ntAS1 58 #define ntB1 62 #define ntC2 65 #define ntCS2 69 #define ntD2 73 #define ntDS2 78 #define ntE2 82 #define ntF2 87 #define ntFS2 93 #define ntG2 98 #define ntGS2 104 #define ntA2 110 #define ntAS2 117 #define ntB2 123 #define ntC3 131 #define ntCS3 139 #define ntD3 147 #define ntDS3 156 #define ntE3 165 #define ntF3 175 #define ntFS3 185 #define ntG3 196 #define ntGS3 208 #define ntA3 220 #define ntAS3 233 #define ntB3 247 #define ntC4 262 //до -1 октава #define ntCS4 277 //до# #define ntD4 294 //ре #define ntDS4 311 //ре# #define ntE4 330 //ми #define ntF4 349 //фа #define ntFS4 370 //фа# #define ntG4 392 //соль #define ntGS4 415 //соль# #define ntA4 440 //ля #define ntAS4 466 //ля# #define ntB4 494 //си #define ntC5 523 //до -2 октава #define ntCS5 554 //до# #define ntD5 587 //ре #define ntDS5 622 //ре# #define ntE5 659 //ми #define ntF5 698 //фа #define ntFS5 740 //фа# #define ntG5 784 //соль #define ntGS5 831 //соль# #define ntA5 880 //ля #define ntAS5 932 //ля# #define ntB5 988 //си #define ntC6 1047 #define ntCS6 1109 #define ntD6 1175 #define ntDS6 1245 #define ntE6 1319 #define ntF6 1397 #define ntFS6 1480 #define ntG6 1568 #define ntGS6 1661 #define ntA6 1760 #define ntAS6 1865 #define ntB6 1976 #define ntC7 2093 #define ntCS7 2217 #define ntD7 2349 #define ntDS7 2489 #define ntE7 2637 #define ntF7 2794 #define ntFS7 2960 #define ntG7 3136 #define ntGS7 3322 #define ntA7 3520 #define ntAS7 3729 #define ntB7 3951 #define ntC8 4186 #define ntCS8 4435 #define ntD8 4699 #define ntDS8 4978 typedef struct { int note; int time; } note_t; const note_t mld[] PROGMEM = {// постой паровоз {ntE4, 250}, {ntE4, 750}, {ntA4, 125}, {ntG4, 125}, {ntF4, 500}, {ntD4, 250}, {ntC4, 250}, {ntB3, 250}, {ntE4, 500}, {ntD4, 250}, {ntC4, 250}, {ntA3, 500}, {ntG4, 250}, {ntG4, 375}, {ntC4, 375}, {ntE4, 250}, {ntG4, 250}, {ntC5, 250}, {ntB4, 250}, {ntA4, 250}, {ntGS4, 1000}, {0, 1000}, {ntE4, 250}, {ntC5, 500}, {ntB4, 250}, {ntC5, 250}, {ntB4, 250}, {ntA4, 500}, {ntE4, 250}, {ntA4, 250}, {ntA4, 250}, {ntG4, 250}, {ntA4, 250}, {ntG4, 250}, {ntF4, 500}, {ntF4, 250}, {ntE4, 500}, {ntG4, 250}, {ntF4, 250}, {ntE4, 250}, {ntD4, 250}, {ntC4, 250}, {ntB3, 250}, {ntA3, 1000}, {0, 1000}, {ntE4, 250}, {ntC5, 500}, {ntB4, 250}, {ntC5, 250}, {ntB4, 250}, {ntA4, 500}, {ntE4, 250}, {ntA4, 250}, {ntA4, 250}, {ntG4, 250}, {ntA4, 250}, {ntG4, 250}, {ntF4, 500}, {ntF4, 250}, {ntE4, 500}, {ntG4, 250}, {ntF4, 250}, {ntE4, 250}, {ntD4, 250}, {ntC4, 250}, {ntB3, 250}, {ntA3, 1000}, {0, 0} }; const byte st0 = 0;// не играть const byte st1 = 1;// играть мелодию 1 class Cl_Beep { protected: byte pin; byte state; byte i; unsigned long past, time; void set(byte s) { state = s; if (s == st0) return; past = millis(); unsigned int note = pgm_read_word(&mld[i].note); time = pgm_read_word(&mld[i].time); i++; if (time == 0) state = st0; else tone(pin, note, time * 0.8); } public: Cl_Beep(byte p): pin(p) {} void init() { set(st0); } void run() { if (millis() - past >= time) set(state); } void play() { i = 0; set(st1); } }; Cl_Beep Beep(/*пин*/8); void setup() { Beep.init(); Beep.play(); } void loop() { Beep.run(); }"рефактринг"=поправить чуть чуть код, а то код не работает
Это дебагинг, это не рефакторинг.
Слова похожие....
Эта тема для сброса сюда очередного квонокода, а остальное просто лишнее.
А шо, разве я не квонокод написал? Классов, правда ема, зато лямбдов девать некуда.
Ладно, буду ещё стараться, мож лучше получится.
А лямбданутее можно.
От брейнфакера слышу!
Вот и выходит что рефакторинг это еще одно модное словечко из лексикона эффективных менеджеров от программирования. :))
Это не модное словечко, отнюдь. Если ты не ел устриц - то про их вкус навряд ли сможешь что-то сказать.
Мне вот интересно: переписывание блинка с дилей на миллис - это рефакторинг или нет?
Сложно сказать без контекста. Если это улучшает структурную организацию кода, повышает его читабельность и документированность, попутно выявляет ошибки - то да, это рефакторинг, и будет рефакторингом, если даже переписать с делай на делай. В противном случае, пмсм - это просто переписывание кода.
А шо, разве я не квонокод написал? Классов, правда ема, зато лямбдов девать некуда.
Ладно, буду ещё стараться, мож лучше получится.
Снимаю шляпу за такой шикарный пример забивания гвоздей микроскопом! Я в культурном шоке, смакую каждую строчку ;)
С одной стороны понятно. Если в коде много строк, то переписывать все долго, трудно и бесплатно. Лучше переписать часть и даже часть части. С другой стороны здесь на форуме открывается много тем, где надо провести "рефактринг"=поправить чуть чуть код, а то код не работает . Хотя всей душой понимаешь, что ТС его код ( а скорее и не его) надо отправить на **й, потому что переписывать надо все а потом еще учить его почему и зачем это надо. Вот и выходит что рефакторинг это еще одно модное словечко из лексикона эффективных менеджеров от программирования. :))
ПС: ЕвгенийП Вы что решились чистить эту тему? Я что нарушил какие-то неписаные правила .!!!
ДАкуя Умничаешь
Мне вот интересно: переписывание блинка с дилей на миллис - это рефакторинг или нет?
Если вам за это заплатят, то скорее всего да. А если на шару то скорее нет. А так музыкальная пауза
Сложно сказать без контекста. Если это улучшает структурную организацию кода, повышает его читабельность и документированность, попутно выявляет ошибки - то да, это рефакторинг, и будет рефакторингом, если даже переписать с делай на делай. В противном случае, пмсм - это просто переписывание кода.
Кстати, музыкальная пауза - фиговенькая. И больше половины дефайнов можно было бы убрать.
А еще, коль скоро мы используем только математически точные длительности, их в дефайны можно было добавить. Дабы легко менять темп.
А если я начал переписывать код, сделал его понятней, убавил багов, но при етом, мать его ети, увеличил на 1кб - это рефакторинг или перевод добра на г....?
А если я начал переписывать код, сделал его понятней, убавил багов, но при етом, мать его ети, увеличил на 1кб - это рефакторинг или перевод добра на г....?
Это пятница :)))))
А если я начал переписывать код, сделал его понятней, убавил багов, но при етом, мать его ети, увеличил на 1кб - это рефакторинг или перевод добра на г....?
А если серьезно, то убранные баги вполне стоят килобайта. Разумеется, если предыдущий килобайт не был последним.
Разумеется, если предыдущий килобайт не был последним.
Предыдущий килобайт - всегда предпоследний, закон-тайга :)))
Для ATMega328. Думал, что выцыганю полкило, а вышло так, что слил килобайт. Прям слёзы в глазах стоят третий день.
Прям слёзы в глазах стоят третий день.
Соберись, третий день - ни в какие ворота :)
Соберись, третий день - ни в какие ворота :)
Дим, а почему Ворота, с маленькой буквы? не уважаешь? :)))))
Соберись, третий день - ни в какие ворота :)
Дим, а почему Ворота, с маленькой буквы? не уважаешь? :)))))
Ля! И точно! Оплошал, блин :))
Шаблон метода класса
class Cl_AAA { public: template<typename T> T & func( T &obj); protected: }; template<typename T> T& Cl_AAA::func( T &obj) { return obj; } template<> byte& Cl_AAA::func(byte &obj) { return obj; } Cl_AAA AAA; void setup() { Serial.begin(9600); int q = -342, w; w = AAA.func(q); Serial.println(w); byte q1 = 123, w1; w1 = AAA.func(q1); Serial.println(w1); } void loop() { }Это для конкурса самых дибильных методов печати 2-х констант?
Подключаем и получаем память дополнительно 4К байт
#include "e24c32.h" void setup() { Serial.begin(9600); outpram.init(); uint16_t addr = 30; float a = 13.18, b; outpram.write(addr, a); //<- загрузить в e24c32 outpram.read(addr, b); //<- прочитать в e24c32 Serial.println(b); } void loop() { }и файл e24c32.h
/**/ #ifndef e24c32_h #define e24c32_h #include <Arduino.h> #include <Wire.h> #define EEPROM__PAGE_SIZE 32 #define EEPROM__WR_BUFFER_SIZE (BUFFER_LENGTH - 2) #define EEPROM__RD_BUFFER_SIZE BUFFER_LENGTH class e24c32 { public: e24c32(byte adr): adr_i2c(adr) {} void init() { Wire.begin(); } byte readByte(word address); void writeByte(word address, byte data); void readBytes(word address, byte length, byte* p_data); void writeBytes(word address, byte length, byte* p_data); template<typename T> T &read (word address, T &obj); template<typename T> T &write(word address, T &obj); private: byte adr_i2c; void writePage (word address, byte length, byte* p_data); void writeBuffer(word address, byte length, byte* p_data); void readBuffer (word address, byte length, byte* p_data); }; byte e24c32::readByte(word address) { Wire.beginTransmission(adr_i2c); Wire.write(address >> 8); Wire.write(address & 0xFF); Wire.endTransmission(); Wire.requestFrom(adr_i2c, (byte)1); byte data = 0; if (Wire.available()) data = Wire.read(); return data; } void e24c32::writeByte( word address, byte data) { Wire.beginTransmission(adr_i2c); Wire.write(address >> 8); Wire.write(address & 0xFF); Wire.write(data); Wire.endTransmission(); } void e24c32::writeBytes(word address, byte length, byte* p_data) { // Write first page if not aligned. byte notAlignedLength = 0; byte pageOffset = address % EEPROM__PAGE_SIZE; if (pageOffset > 0) { notAlignedLength = EEPROM__PAGE_SIZE - pageOffset; if (length < notAlignedLength) notAlignedLength = length; writePage(address, notAlignedLength, p_data); length -= notAlignedLength; } if (length > 0) { address += notAlignedLength; p_data += notAlignedLength; // Write complete and aligned pages. byte pageCount = length / EEPROM__PAGE_SIZE; for (byte i = 0; i < pageCount; i++) { writePage(address, EEPROM__PAGE_SIZE, p_data); address += EEPROM__PAGE_SIZE; p_data += EEPROM__PAGE_SIZE; length -= EEPROM__PAGE_SIZE; } if (length > 0) writePage(address, length, p_data); // Write remaining uncomplete page. } } void e24c32::readBytes (word address, byte length, byte* p_data) { byte bufferCount = length / EEPROM__RD_BUFFER_SIZE; for (byte i = 0; i < bufferCount; i++) { word offset = i * EEPROM__RD_BUFFER_SIZE; readBuffer(address + offset, EEPROM__RD_BUFFER_SIZE, p_data + offset); } byte remainingBytes = length % EEPROM__RD_BUFFER_SIZE; word offset = length - remainingBytes; readBuffer(address + offset, remainingBytes, p_data + offset); } void e24c32::writePage(word address, byte length, byte* p_data) { // Write complete buffers. byte bufferCount = length / EEPROM__WR_BUFFER_SIZE; for (byte i = 0; i < bufferCount; i++) { byte offset = i * EEPROM__WR_BUFFER_SIZE; writeBuffer(address + offset, EEPROM__WR_BUFFER_SIZE, p_data + offset); } // Write remaining bytes. byte remainingBytes = length % EEPROM__WR_BUFFER_SIZE; byte offset = length - remainingBytes; writeBuffer(address + offset, remainingBytes, p_data + offset); } template<typename T> T& e24c32::read(word address, T &obj) { readBytes(address, sizeof(T), (byte*)&obj); return obj; } template<> byte & e24c32::read (word address, byte &obj) { return obj = readByte(address); } template<typename T> T & e24c32::write (word address, T &obj) { writeBytes(address, sizeof(T),(byte*)&obj); return obj; } template<> byte & e24c32::write(word address, byte &obj) { writeByte(address, obj); return obj; } void e24c32::writeBuffer (word address, byte length, byte* p_data) { Wire.beginTransmission(adr_i2c); Wire.write(address >> 8); Wire.write(address & 0xFF); for (byte i = 0; i < length; i++) Wire.write(p_data[i]); Wire.endTransmission(); // Write cycle time (tWR). See EEPROM memory datasheet for more details. delay(10); } void e24c32::readBuffer (word address, byte length, byte* p_data) { Wire.beginTransmission(adr_i2c); Wire.write(address >> 8); Wire.write(address & 0xFF); Wire.endTransmission(); Wire.requestFrom(adr_i2c, length); for (byte i = 0; i < length; i++) if (Wire.available()) p_data[i] = Wire.read(); } static e24c32 outpram(/* адр i2c*/0x57); #endif // e24c32_hШаблон метода класса
class Cl_AAA { public: template<typename T> T & func( T &obj); protected: }; template<typename T> T& Cl_AAA::func( T &obj) { return obj; } template<> byte& Cl_AAA::func(byte &obj) { return obj; } Cl_AAA AAA; void setup() { Serial.begin(9600); int q = -342, w; w = AAA.func(q); Serial.println(w); byte q1 = 123, w1; w1 = AAA.func(q1); Serial.println(w1); } void loop() { }не пойму в чём цимес?
А для чего строки №№ 9-11? (скетч из #135)
template<> byte& Cl_AAA::func(byte &obj) { return obj; }Может я чего не заметил, но мне кажется. что строки №№ 9-11 можно удалить и ничего не изменится. Я чего-то недопонял?
В любом случае, я не консультирую по этому коду и не помогаю решать связанные с ним вопросы. Сейчас сделаю исключение, но впредь, имейте в виду.
ПС: учитель это не тот кто учит, а у того кого вы учитесь. Код здесь это просто личная записная книжка выложенная для публичного просмотра. Если кому интересно учится на моем коде я не возражаю. Но меня учить не надо. Я прекрасно вижу свои ошибки. А если не увижу сейчас , то увижу потом,для чего я и открыл эту тему.
Спасибо. Долго не мог понять зачем Вы это выкладываете. Пожалуй поучусь у Вас тоже .. в смысле попробую понять где и как смогу применить этот подход. Надеюсь не возражаете? Критиковать и комментировать - не буду, обещаю.
Если это личная записаня книжка, то почему она на публичном ресурсе? А если публичная, то может Вам как-то поадекватнее реагировать на вопросы, которые Вам задают? Впрочем, это, конечно, не моё дело.
Пух, не забывай, что буфер у Wire 32 байта, и когда ты страницу хочешь записать, адрес ячейки куда писать займет в буфере 2 байта, и записать потом ты можешь еще 30, а 2 последних в ROM не попадут.
Код твой я не читал, я просто спрашиваю, знаешь ли ты абэтом
Похоже и wire придется переписывать. А тестировать надо многоватенько.
Воспользуйтесь этим драйвером I2C, тут буфер внешний. Сколько надо - столько и заявите и даже статически:
Где-то был вариант с ведением логов передач и ошибок, если надо, поищу.
Строку 42 - можно удалить и в строках 212,213 заменить макрос pinOut() на digitalWrite() на ноги вашего I2C. Больше нигде этот хидер тут не нужен вроде бы..
"Пропал дом!" :(
Похоже, что не только Wire переписывать надо, но и вообще менять всю систему.
Именно систему! Да что систему менять - цивилизацию менять надо, планетарно мыслить! И вселенски!
ПС. Два дебила - это сила, а у нас здесь - коллектив!