Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Котуинко

Вс июн 02, 2019 21:57:34

ВНИМАНИЮ ПОЛЬЗОВАТЕЛЕЙ АДУРИНО_IDE!!!
Если на Вашем ПК установлена WIN32 (32-х разрядная версия)
категорически не рекомендуется обновлять

esp8266 by ESP8266 Community версия 2,5,0

на более поздние версии, имеющие в своем составе компоненты WIN64.

В случае случайной установки обновления (старше 2.5.0) лечение сначала
"удалить"
затем установить последний вариант
esp8266 by ESP8266 Community версия 2,5,0
выбрав версию ВРУЧНУЮ.
8)

И вдобавок к предыдущему о sins5 - протупил в отношении индикации ошибки датчика.
В новом варианте квадратик индикации включения активного элемента выводится на дисплей, а вот заблокировать его при индикации ошибки CRC/ошибки "датчик не отвечает" позабыл...
:oops:
Позже при доработках исправлю...
:write:

Re: Котуинко

Пт июн 07, 2019 10:36:29

Подправил ошибки и несколько изменил схемку
http://img.radiokot.ru/files/20529/1vxh8z7115.JPG
(перенесен вывод управления силовым ключом и добавлена цепочка контроля разрядки аккумулятора).
Добавлено отключение при разряде батарейки ниже 2,8-2,9 вольта (Lou bA).
snis_6.rar
(556.14 KiB) Скачиваний: 196

Вобщем... неплохо поигрался...
:roll:
Попала в лапы парочка вот таких вкусняшек
Изображение
:hunger:
Надо поиграться...
:write:

Re: Котуинко

Вс июн 09, 2019 20:57:34

Однако этот JDY-40 из беспроводных штука весьма вкусненькая...
:hunger:
Прицепил из своего наборчика набросок для теста с ПК
http://img.radiokot.ru/files/20529/1x05ykuq3c.GIF
http://img.radiokot.ru/files/20529/1x06097ksh.jpg
Теперь накидать чего из прикладушек для проверки канала СОМ радиопорта...
Скорее всего на про-мини...
Да определить вероятность помех... и как настраивать параметры...
Но... то по ходу ленивого размышления...
:roll:
:write:

Re: Котуинко

Чт июн 13, 2019 08:44:08

Весьма неплохой вариант для "почитамс"
https://www.rlocman.ru/book/book.html?di=532971
"ARDUINO: от азов программирования до создания практических устройств
Автор: Белов А.В.
Год: 2018
Издательство: Наука и Техника
ISBN: 978-5-94387-884-8
..."
имеется в домашней библиотеке...
:hunger:

Re: Котуинко

Сб июн 22, 2019 14:03:40

ГЫММ....
Раньше как-то особо с интегрированной ЕЕПРОМкой в АВР не занимался...
Однако последнее время обратил внимание, что даже в "пустых" (свежепроданных и/или отлежавшихся в хранении) МК ЕЕПРОМка не всегда вся заполнена 0xFF...
Причем иногда картинка прочтения меняется просто после установки/снятия МК из панельки программатора...
Помимо прочего "мусор" также набрасывает и в ЕЕПРОМку ардуино-нано... Вот только отловить из-за чего пока не удалось...
Отметил лишь случайные сбои при подаче питания. Как предположение.
Ежли чего явно обнаружится - тогда и выложу как "область повышенного внимания" - два-три случая вроде "не фак"...
:dont_know:

Re: Котуинко

Вт июн 25, 2019 06:06:18

Малость побаловался с вводом номинала уставки - обнаружил сбои по автоограничениям номинала при вводе...
:(
Исправил...
snis_7.rar
(34.99 KiB) Скачиваний: 175

теперь значения более максимально-допустимых ввести не удастся при любой комбинации.
:roll:
Возможно чего еще добавится...
:write:

Re: Котуинко

Сб июл 13, 2019 17:04:56

ЛЕТО...ЖАРА...
РАСКОПКИ АДУРИНЫ...
:(
Что для выноса текстовки можно применить три варианта шаблона - два как у класса и один как в Си...
Пока промолчу... - в стадии осмысления... но хотя бы частично понимаемо...
:write:
А вот как такой казус появился мне совсем непонятно...

Спойлер
Код:
byte datas[9]{1,3,5,7,9,11,15,22,0};
byte flag;

#define crc_7 7 // функция обрабатывает CRC7 (адресный блок)
#define crc_8 8 // функция обрабатывает CRC8 (полный блокнот)
   
byte xpcrc(byte*, byte); // самоделка программного CRC

//----------

void setup() {
  // put your setup code here, to run once:

flag = xpcrc(datas, crc_8);
// datas[crc_8] = flag;

}

void loop() {
  // put your main code here, to run repeatedly:

}

//----------

byte xpcrc(byte *pad, byte mod)
 {
   byte tmp_crc = 0; byte ret_data = 0;
 for (byte cnt=0; cnt<mod; cnt++)
   {
    byte tmp = pad[cnt];//*(pad + cnt);
    for (byte a=0; a<8; a++)
     {
       if ((tmp_crc ^ tmp) & 0x01) // по результату обработки первого узла
        {
         tmp_crc = ((tmp_crc ^ 0x18) >> 1) | 0x80;
        } // если результату обработки первого узла=1
       else
        {
         tmp_crc = (tmp_crc >> 1) & 0x7F;
        } // если результату обработки первого узла=0
       tmp = tmp >> 1; // сдвигаем текущие данные
     }
   }
   ret_data=tmp_crc;
  return ret_data;
 }

в результате
"Скетч использует 444 байт (1%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт."
а теперь чуток изменим
Спойлер
Код:
byte datas[9]{1,3,5,7,9,11,15,22,0};
byte flag;

#define crc_7 7 // функция обрабатывает CRC7 (адресный блок)
#define crc_8 8 // функция обрабатывает CRC8 (полный блокнот)
   
byte xpcrc(byte*, byte); // самоделка программного CRC

//----------

void setup() {
  // put your setup code here, to run once:

flag = xpcrc(datas, crc_8);
 datas[crc_8] = flag;

}

void loop() {
  // put your main code here, to run repeatedly:

}

//----------

byte xpcrc(byte *pad, byte mod)
 {
   byte tmp_crc = 0; byte ret_data = 0;
 for (byte cnt=0; cnt<mod; cnt++)
   {
    byte tmp = pad[cnt];//*(pad + cnt);
    for (byte a=0; a<8; a++)
     {
       if ((tmp_crc ^ tmp) & 0x01) // по результату обработки первого узла
        {
         tmp_crc = ((tmp_crc ^ 0x18) >> 1) | 0x80;
        } // если результату обработки первого узла=1
       else
        {
         tmp_crc = (tmp_crc >> 1) & 0x7F;
        } // если результату обработки первого узла=0
       tmp = tmp >> 1; // сдвигаем текущие данные
     }
   }
   ret_data=tmp_crc;
  return ret_data;
 }

и...
"Скетч использует 524 байт (1%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт."
:shock:
неуж-то
Код:
 datas[crc_8] = flag;

где всего-то поместить байт в ячейку массива (оба заранее объявлены и инициализированы)
ЖРЕТЬ 10 байт ОЗУ - практически столько же, сколько и сам массив?...
:dont_know:
на ассемблере такого не случалось встречать...
:roll:
Последний раз редактировалось BOB51 Сб июл 13, 2019 20:56:28, всего редактировалось 1 раз.

Re: Котуинко

Сб июл 13, 2019 17:27:51

на ассемблере такого не случалось встречать...

В первый раз компилятор не выделял память ни под массив, ни под flag(9+1 байт), т.к. они не используются, потому во-второй раз и получилось +10 байт RAM. То же самое с функцией, первый раз ее в коде не было вообще. А ассм слишком примитивен, ему даешь посчитать 2+2 и он считает, в то время как С просто подставит 4.

Re: Котуинко

Сб июл 13, 2019 20:48:19

Как это массив не используется?
А что тогда функция считает-то не данные из массива?
:roll:
Проход по массиву в режиме чтения данных выполняется В ОБЕИХ СЛУЧАЯХ.
А вот загрузка ячейки - только в одном из вариантов (он-то и дает +10 байт).
(кстати в симуляторе UnoArduSim массив сразу появляется в "полном виде" - вышеприведенный черновичок под него и подгонялся, чтоб "взглянуть на ход работы")
Т.е. если уж обсчет выполняется, то массив в памяти существует.
Оттуда и 9 байт ОЗУ - собственно массив и РВХ должны быть активны, но РВХ компилятор может и "упрятать" - они только в пределах функции появляются).
А вот откуда еще 10 добавляется?
:roll:

Re: Котуинко

Сб июл 13, 2019 21:05:25

Как это массив не используется?
А что тогда функция считает-то не данные из массива?

Функция ничего не считает, потому что возвращаемый ей результат нигде не используется, а раз не нужна функция, то зачем нужен массив?
В качестве простой проверки можешь сделать так:
Код:
flag = xpcrc(datas, crc_8);
// datas[crc_8] = flag;

в потом так:
Код:
// flag = xpcrc(datas, crc_8);
// datas[crc_8] = flag;

С оптимизацией разницы быть не должно.

Re: Котуинко

Вс июл 14, 2019 07:24:38

УВЫ...
Дело в том, что это набросок из более полного варианта.
А там возвращался или байт CRC или флаг результата сравнения
расчетной CRC и последнего байта массива.
В обеих случаях возврат результата вычисления - однако при возврате CRC 19 байт(возврат +занесение в последнюю ячейку массива), а при возврате результата сравнения 9 (но тогда "обратное заполнение" ячейки не производилось).
Собственно тот "казус" и подвел под проверку примитива.
Ибо... с точки зрения распределения памяти МК - ни по "максимуму" ни по оптимальному варианту подобный результат не подходит.
Правда с точки зрения "железного ассемблера" и работы без оптимизаторов:
9 байт массив - фиксированный минимум
остальное временно используемое (фиксируется для отчета о максимальном объеме ОЗУ)
2 байта указатель (начального) адреса массива
1 байт временного буфера
1 байт накопителя результата
1 байт счетчика байт
1 байт счетчика бит
на всякий случай добавим указатель стека - еще 2 байта
итоговый максимум 17 байт...
если стоит особняком загрузка ячейки по указанному адресу со смещением и не константными данными, а через регистры - +4 байта.
В случае "скрытия" РВХ от вычислений при исполнении с передачей CRC как байта результата работы функции в последний байт массива должно быть где-то максимум 9+4+1 - 14 байт.
Ну да ... Оставим сей вопрос "на совести компилятора" с выводом - "не верь максимальным результатам выводимых сообщений".
:twisted:
"Чистый ассемблер" таки много проще и яснее в работе.
8)

Добавлено after 8 hours 51 minute 58 seconds:
НА ЗАМЕТКУ
Схемное и монтажное представление для модуль- платок ардуино-нано и ардуино-про-мини в сплане и лейоуте
(в моем представлении - может у кого лучше получится):
http://img.radiokot.ru/files/20529/1y24k7z8p0.GIF
http://img.radiokot.ru/files/20529/1y24k5nheq.GIF
и архив с файлами splan&layout
трафареты схемплат.rar
(27.74 KiB) Скачиваний: 186

чтоб можно было хош не "на пальцах" изъясняться на тему схемотехники конструкций.
8)

Re: Котуинко

Вс июл 21, 2019 18:51:43

ПОБОЧНЫЙ ПРОДУКТ...
По предыдущим опытам с WS2812 и аттини45 в режиме энергосбережения
остался осадок от нестабильного срабатывания.
Да и работа с адуриньями в отношении перевода оных в режим отключения
энергопотребления весьма неприятная штука...
Удобненько бы применить поляризованное реле...
Однако подборка и поиски подобного в отношении доступности и
удобоваримых параметров/габаритов не слишком успешны.
Посему появилась воть такая концепт-схема на PIC10F200
http://img.radiokot.ru/files/20529/1yadgnglbb.GIF
(макетка http://img.radiokot.ru/files/20529/1yadqs6a6v.jpg)
В качестве кнопы на макете применена емкостная "китаянка"
http://img.radiokot.ru/files/20529/1mkbqcj7fc.jpg
http://img.radiokot.ru/files/20529/1mkbqhklf8.jpg
и ранее заготовленные "переходнички" с ПИКушкой и IRLML6401
Прожка также готова - но в стадии "сыросварения" - требуется таки и
"окультуривание редакции" и проверка в режиме обкатки временем.
:write:
Прицепил на пробу к термостату на адуринке - только для теста автоотключения (соответственно изменения во СКОТче)
РАБОТАЕТ ЗАРАЗА!
:hunger:
Остается проверить на сколько хватит аккумулятора (прожорливость) при текущем макете.
8)
Чуток подчищенный исходник
sleep_key.rar
(334.46 KiB) Скачиваний: 181

но... только вечерком проверю "в металле" - правда из чистки там ничего существенного...
Однако лучше таки перестраховаться.
(калибровка там ОТ МОЕГО ПИКА - при "пересадке" не забудьте заменить соответствующую константу и перекомпилировать!)
:wink:
Проверил.
Как ни странно подправленное - таки работает устойчиво...
:tea:

Re: Котуинко

Пн июл 29, 2019 12:31:40

Обновенная версия симулятора ардуино-уно:
https://www.sites.google.com/site/unoardusim/services
UnoArduSimV2.4 Jun 3, 2019
:hunger:

Re: Котуинко

Вт июл 30, 2019 12:51:59

АДУРИНКА.
Воспоминания и размышления.

Попробую немножко "отсебятинки" из недр инета и самосадизмом добытой информации поделиться.
Может не всегда "кошерно приготовленной".
Те вопросы, что меня интересовали, да так и остались без ответов.

Касательно удобного разделения основной программы (*.ino файла) на два раздела.

Код:
void setup() {}
void loop() {}


Собственно "в дебрях" скрытой от пользователя части компилятора для практической работы
важно следующее:
функция void loop() {} представляет из себя бесконечный цикл вида
for (i;i;i){}
с заранее заготовленным внутри функционалом обработки аппаратного USART.
причем даже в случае, если тот обмен не активирован применением в
void setup() {
Serial.begin();}
фрагмент кода там ВСЕГДА остается.
Посему для уменьшения размера кода (если не предусмотрено использование стандартного функционала serial) можно ограничиваться только разделом setup, обрамляя свою программу в какой-либо бесконечный цикл.
Правда это "книжная рекомендация" - на практическом тесте экономии байт с 12...
:(

О написании библиотек... Или скорее о выносе части программного текста за пределы файла *.ino
текущего проекта.

Как-то уж весьма смуторно там перемешано.
Попробовал разные варианты, да заготовки нашкарябал...
получилось вот такое обобщение:
СпойлерВеншние файлы в многофайловом проекте для ардуино.

Создание подключенных внешних файлов для проекта ардуино может выполняться в трех вариантах.

Самый простой — создание двух файлов
*.h – заголовочного и
*.ccp — собственно самого текста
Данные файлы должны размещаться в одной папке вместе с основным файлом проекта.
Вариант исполнения в папке проекта inc_test0

К сожалению мой любимый редактор DPAD не создает *.cpp файл, да и кодировка в ардуино IDE может создать проблемы.
Возможно и в других внешних редакторах чего-то подобного вылезти может.
Посему предпочтение копированию шаблонных shaps.h и shaps.cpp в конкретный проект, а затем их переименование и наполнение конкретным содержимым.

За основу теста взята программка программного вычисления DALLAS CRC.
Эта прожка может быть выполнена во всех трех возможных вариантах «внешнего исполнения»

Итак …
Выполняем простой вынос фрагмента программы за пределы основного файла *.ino

создаем dscrc.h файл:

Код:
/* ---------- */
/*  заголовочный файл библиотеки программного обработчика    */
/*                    Dallas CRC7/CRC8                   */
//----------
 #ifndef dscrc_H        // Блокируем повторное включение этого модуля
 #define dscrc_H

//----------
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif
//----------

#define crc_7 7 // функция обрабатывает CRC7 (адресный блок)
#define crc_8 8 // функция обрабатывает CRC8 (полный блокнот)
#define test_crc 0 // проверка, при ошибке функция возвращает true
#define gen_crc 1 // генерация с подстановкой в последний
               // байт блокнота, функция возвращает значение СКС
   
byte crc_mlan(byte*, byte, byte); // самоделка программного CRC

#endif


В отличии от обычного файла СИ в заголовочном файле ОБЯЗАТЕЛЬНО присутствует или блок

Код:
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif


для совместимости с очень старыми IDE
или просто строчка

Код:
#include "Arduino.h"


для подключения «спецдобавок» более современных IDE (1.8.9 например).

Теперь переходим к созданию dscrc.ccp файла...

Код:
/* ---------- */
/*  исполнительный файл библиотеки программного обработчика    */
/*                    Dallas CRC7/CRC8                   */
//----------

//******************************************************************
//  Секция include: здесь подключается заголовочный файл к модулю
//******************************************************************

 #include "dscrc.h" // заголовочный *.h файл текущего проекта

// ----------
// если задано task=test_crc (task=0) то функция
// возвращает или 0 при совпадении CRC
// или 1 при ошибке CRC
// если задано task=gen_crc (task=1) то функция
// возвращает собственно байт CRC
// *pad = адресу начала буфер-массива данных "блокнота"
// mod = crc_7 (mod = 7) для работы с адресным пакетом (8 байт)
// или
// mod = crc_8 (mod = 8) для работы с пакетом данных (9 байт)

//byte dscrc::crc_mlan(byte *pad, byte mod, byte task)
byte crc_mlan(byte *pad, byte mod, byte task)
 {
   byte tmp_crc = 0; byte ret_data = 0;
 for (byte cnt=0; cnt<mod; cnt++)
   {
    byte tmp = pad[cnt];//*(pad + cnt);
    for (byte a=0; a<8; a++)
     {
       if ((tmp_crc ^ tmp) & 0x01) // по результату обработки первого узла
        {
         tmp_crc = ((tmp_crc ^ 0x18) >> 1) | 0x80;
        } // если результату обработки первого узла=1
       else
        {
         tmp_crc = (tmp_crc >> 1) & 0x7F;
        } // если результату обработки первого узла=0
       tmp = tmp >> 1; // сдвигаем текущие данные
     }
   }
  if (task)
   {
    ret_data = tmp_crc; // результат в байте возврата
    pad[mod] = tmp_crc; //*(pad + mod) = tmp_crc; результат в последнем байте блокнота
   }
  else
    {
     ret_data = (tmp_crc == pad[mod]) ? 0 : 1 ; //(tmp_crc == *(pad + mod)) ? 0 : 1 ;
    }
  return ret_data;
 }


вот собственно и все...
Теперь сам файл inc_test0.ino :

Код:
#include "dscrc.h"

byte datas[9]{1,3,5,7,9,11,15,22,0};
byte flag;

void setup() {
  // put your setup code here, to run once:

 flag = crc_mlan(datas, 8, 1);

}

void loop() {
  // put your main code here, to run repeatedly:

}


в результате имеем сообщение компилятора:
«Скетч использует 524 байт (1%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.»

Вот такой Простой Вынос части программы за пределы основного файла.

ВТОРОЙ ВАРИАНТ.
Это довольно широко описанный вариант создания класса, имеющего возможность создания нескольких экземпляров класса.
Чаще всего применяется для протоколов обмена с использованием одного/нескольких наборов внешних выводов при работе с датчиками, дисплеями и прочими устройствами.
В данном случае может иметь место несколько массивов «блокнота», привязанных к соответствующим программным обработчикам.
Будем размещать все файлы для начала также в текущей папке.
Чтоб их потом «вытащить» в самих файлах уже ничего переделывать не понадобится.

Однако сами файлы выносимого фрагмента придется несколько подправить...
Выносим указатель на массив блокнота в конструктор класса. А в самой функции убираем его из явно задаваемых параметров.

Итогом
заголовочный файл dscrc.h для inc_test1.ino будет иметь вид:

Код:
/* ---------- */
/*  заголовочный файл библиотеки программного обработчика    */
/*                    Dallas CRC7/CRC8                   */
//----------
#ifndef dscrc_H        // Блокируем повторное включение этого модуля
#define dscrc_H

//----------
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif
//----------

class dscrc
{
public:
// объявление конструктора
   dscrc (byte*); // в текущем приложении это указатель на массив "блокнота"

// объявление (и начальная инициализация) открытых членов класса
#define crc_7 7 // функция обрабатывает CRC7 (адресный блок)
#define crc_8 8 // функция обрабатывает CRC8 (полный блокнот)
#define test_crc 0 // проверка, при ошибке функция возвращает true
#define gen_crc 1 // генерация с подстановкой в последний
               // байт блокнота, функция возвращает значение СКС

// объявление функций внешнего доступа
byte crc_mlan(byte, byte); // самоделка программного CRC
// в данном случае целевой массив блокнота заявляется
// в основном файле inc_test1.ino при создании экземпляра класса

private:
// объявление закрытых членов класса
 byte *pad; // объявляем закрытый член класса
    // копия указателя массива блокнота для внутренних нужд функции
 
}; // обязательное заключительное ";"
#endif


файл dscrc.ccp принимает вид:

Код:
/* ---------- */
/*  исполнительный файл библиотеки программного обработчика    */
/*                    Dallas CRC7/CRC8                   */
//----------

//********************************************************************
//  Секция include: здесь подключается заголовочный файл к модулю
//********************************************************************

 #include "dscrc.h" // заголовочный *.h файл текущего проекта

// ----------
// если задано task=test_crc (task=0) то функция
// возвращает или 0 при совпадении CRC
// или 1 при ошибке CRC
// если задано task=gen_crc (task=1) то функция
// возвращает собственно байт CRC
// *pad = адресу начала буфер-массива данных "блокнота"
// mod = crc_7 (mod = 7) для работы с адресным пакетом (8 байт)
// или
// mod = crc_8 (mod = 8) для работы с пакетом данных (9 байт)

/*
 *  конструктор
 * задаем соответствие физических линий интерфейса
 * или данных/переменных главной программы
 * закрытым переменным членам класса
*/

 dscrc::dscrc(byte *datas)
 {
  pad = datas; // указатель на массив блокнота привязывается к
             // закрытому члену данного экземпляра класса
 }

byte dscrc::crc_mlan(byte mod, byte task)
 {
   byte tmp_crc = 0; byte ret_data = 0;
 for (byte cnt=0; cnt<mod; cnt++)
   {
    byte tmp = pad[cnt];//*(pad + cnt);
    for (byte a=0; a<8; a++)
     {
       if ((tmp_crc ^ tmp) & 0x01) // по результату обработки первого узла
        {
         tmp_crc = ((tmp_crc ^ 0x18) >> 1) | 0x80;
        } // если результату обработки первого узла=1
       else
        {
         tmp_crc = (tmp_crc >> 1) & 0x7F;
        } // если результату обработки первого узла=0
       tmp = tmp >> 1; // сдвигаем текущие данные
     }
   }
  if (task)
   {
    ret_data = tmp_crc; // результат в байте возврата
    pad[mod] = tmp_crc; //*(pad + mod) = tmp_crc; результат в последнем байте блокнота
   }
  else
    {
     ret_data = (tmp_crc == pad[mod]) ? 0 : 1 ; //(tmp_crc == *(pad + mod)) ? 0 : 1 ;
    }
  return ret_data;
 }

А сам файл основной программы inc_test1.ino :

Код:
#include "dscrc.h"

byte datas[9]{1,3,5,7,9,11,15,22,0};
byte flag;

// выполнение конструктора для создания экземпляра класса
// и задания имени этого экземпляра класса
// в данном примере my_dscrc является экземпляром класса dscrc

  dscrc my_dscrc (datas);

void setup() {
  // put your setup code here, to run once:

flag = my_dscrc.crc_mlan(8, 1);

}

void loop() {
  // put your main code here, to run repeatedly:

}


в результате имеем сообщение компилятора:
“Скетч использует 582 байт (1%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 21 байт (1%) динамической памяти, оставляя 2027 байт для локальных переменных. Максимум: 2048 байт.”

В ходу также и ТРЕТИЙ ВАРИАНТ — это класс без экземпляров.
Т.е. при таком варианте имеется всего ЕДИНСТВЕННО ВОЗМОЖНЫЙ экземпляр класса.
Собственно разновидность первого варианта, реализованная как класс.
Однако в таком случае не применяется конструктор в главном файле программы (*.ino). А имя класса задается как EXTERN.

Заголовочный файл dscrc.h для inc_test2.ino будет иметь вид:

Код:
/* ---------- */
/*  заголовочный файл библиотеки программного обработчика    */
/*                    Dallas CRC7/CRC8                   */
//----------
 #ifndef dscrc_H        // Блокируем повторное включение этого модуля
 #define dscrc_H

//----------
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif
//----------

class dscrc
{
public:

// объявление (и начальная инициализация) открытых членов класса
#define crc_7 7 // функция обрабатывает CRC7 (адресный блок)
#define crc_8 8 // функция обрабатывает CRC8 (полный блокнот)
#define test_crc 0 // проверка, при ошибке функция возвращает true
#define gen_crc 1 // генерация с подстановкой в последний
               // байт блокнота, функция возвращает значение СКС

// объявление функций внешнего доступа
byte crc_mlan(byte*, byte, byte); // самоделка программного CRC
// в данном случае целевой массив блокнрта заявляется
// в основном файле inc_test1.ino при создании экземпляра класса

private:
// объявление закрытых членов класса
 
}; // обязательное заключительное ";"

 extern dscrc my_dscrc; // присваиваем прикладное имя my_dscrc

#endif


файл dscrc.ccp принимает вид:

Код:
/* ---------- */
/*  исполнительный файл библиотеки программного обработчика    */
/*                    Dallas CRC7/CRC8                   */
//----------

//*****************************************************************
//  Секция include: здесь подключается заголовочный файл к модулю
//******************************************************************

 #include "dscrc.h" // заголовочный *.h файл текущего проекта

// ----------
// если задано task=test_crc (task=0) то функция
// возвращает или 0 при совпадении CRC
// или 1 при ошибке CRC
// если задано task=gen_crc (task=1) то функция
// возвращает собственно байт CRC
// *pad = адресу начала буфер-массива данных "блокнота"
// mod = crc_7 (mod = 7) для работы с адресным пакетом (8 байт)
// или
// mod = crc_8 (mod = 8) для работы с пакетом данных (9 байт)

byte dscrc::crc_mlan(byte *pad, byte mod, byte task)
 {
   byte tmp_crc = 0; byte ret_data = 0;
 for (byte cnt=0; cnt<mod; cnt++)
   {
    byte tmp = pad[cnt];//*(pad + cnt);
    for (byte a=0; a<8; a++)
     {
       if ((tmp_crc ^ tmp) & 0x01) // по результату обработки первого узла
        {
         tmp_crc = ((tmp_crc ^ 0x18) >> 1) | 0x80;
        } // если результату обработки первого узла=1
       else
        {
         tmp_crc = (tmp_crc >> 1) & 0x7F;
        } // если результату обработки первого узла=0
       tmp = tmp >> 1; // сдвигаем текущие данные
     }
   }
  if (task)
   {
    ret_data = tmp_crc; // результат в байте возврата
    pad[mod] = tmp_crc; //*(pad + mod) = tmp_crc; результат в последнем байте блокнота
   }
  else
    {
     ret_data = (tmp_crc == pad[mod]) ? 0 : 1 ; //(tmp_crc == *(pad + mod)) ? 0 : 1 ;
    }
  return ret_data;
 }

А сам файл основной программы inc_test2.ino :

Код:
#include "dscrc.h"

byte datas[9]{1,3,5,7,9,11,15,22,0};
byte flag;

void setup() {
  // put your setup code here, to run once:

flag = my_dscrc.crc_mlan(datas, 8, 1);

}

void loop() {
  // put your main code here, to run repeatedly:

}

в результате имеем сообщение компилятора:
“Скетч использует 524 байт (1%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.”

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


Ну и архивки с тест-прожками
inc_test0.rar
(2.56 KiB) Скачиваний: 183

inc_test1.rar
(3.09 KiB) Скачиваний: 185

inc_test2.rar
(2.8 KiB) Скачиваний: 215

ВОТЬ...
В следующий раз добавлю дополнения по функциям референса,
что потихоньку в заметки на распечатках описаний накопились.
:write:

Re: Котуинко

Вт июл 30, 2019 13:31:17

BOB51 писал(а):Правда это "книжная рекомендация" - на практическом тесте экономии байт с 12...
я слежу за вашим "блогом", BOB51, поскольку мне интересен избранный вами тернистый путь "первооткрывателя" Америки :)
но могу вам сказать, что у вас сложилось катастрофически неверное представление о языке С/С++, соответственно вы сами себя обрекли на "открытия"... например, недавно вас удивляло, как заремаривание большого куска кода практически никак не влияет на итоговый размер прошивки... теперь вот тоже удивляетесь, что выбрасывание "лишнего" экономит всего 12 байт...

постарайтесь осознать и смириться с тем фактом, что оптимизатор современного компилятора анализирует написанный вами код и самостоятельно выбрасывает из него участки, которые никогда не будут исполнены. именно по этой причине вы можете заремарить то, что и так никогда не будет работать, и удивляться... например:
Код:
int var = 1;
if(!var){
  // здесь 250 килобайт кода
} else {
  var = 1;
}
в этом примере, как бы вы не модифицировали упомянутые 250 килобайт кода, вы совершенно не увидите разницы в размере итоговой прошивки! потому как согласно написанному, эти 250 килобайт никогда не будут выполняться - зачем же помещать в итоговую прошивку этот код?!

аналогично поступит компилятор (не всякий, конечно, и не всегда, но в общем случае - да) с выделенными массивами, к которым никто никогда не обращается... и со многими другими вещами. например, он запросто может проинлайнить функцию, и вы не обнаружите в коде оператора ret или rcall. а может сделать ровно наоборот - добавить вызов функции там, где вы даже и не ожидаете (например, для выполнения пролога и эпилога функций). и сделает это он по вашей команде "оптимизировать" код, но сделает по-своему.

так что вы просто окончательно определитесь: либо вы осваиваете С/С++ во всей их красе, либо так и остаетесь ассемблерщиком, не осознающим, что для сбора урожая с сотни гектаров пашни давно придуманы комбайны, и никто не пользуется лопатой...

Re: Котуинко

Вт июл 30, 2019 14:09:07

Вот тут-то и разница между ассемблерщиком и СИшником!
Надо как-то уж не столь резко делить неделимое.
И от ассемблера чего повкуснее, и от гибрида СИ адуринкина.
8)
Всякие крайности вредны и для здоровья и для дела.
Лучше бы чего про вынос текстовки за пределы основного файла прокомментировали - может я чего упустил или неверно истолковал.
Да и насчет структуры файлов *.ino к сожалению не от местных ГУРУ, а из случайных забугорных книж данные вытряхнуть удалось.
А ЖАЛЬ...
:(
АДУРИНИНУ как вид микросборок давно повсеместно применяют.
Только направленность популяризации в большинстве случаев однобоко упрощенная - делают пользователей, а не тех, кто САМОСТОЯТЕЛЬНО устройство соорудить сможет (или это уже наши "цензорские фильтры" пропускают не совсем свеже-корректное в данном направлении).
:beer:

Re: Котуинко

Вт июл 30, 2019 14:15:55

BOB51 писал(а):Лучше бы чего про вынос текстовки за пределы основного файла прокомментировали
я не использую C++ в принципе, не владею. и желания овладевать нет совсем. конечно, для ознакомления с исходниками "библиотек" для ардуины, моих знаний С++ хватает, но комментировать - увольте, боюсь, сяду в лужу... слишком там много нюансов...

я сам пользуюсь (и всем рекомендую) старым добрым Си. тут я еще могу что-то посоветовать, да и то не всегда "в строгом соответствии со стандартом" :dont_know:

Re: Котуинко

Вт июл 30, 2019 15:33:04

ЖАЛЬ И ПЕЧАЛЬКА...
:(
Ибо... адурина - великий ГИБРИД.
При просмотре библиотек и примеров там столько всяко-разного стиля...
:facepalm:
Оные то кем-то написаны, а как самому наиболее верно составить?...
Где СИ++, где чистый СИ мелькает. А где и еще чего пострашнее...
Только вот из подключаемого мне самому удалось лишь *.h да *.cpp
приткнуть. На простой *.с матюкается однако...
Вроде еще какой-то вариант - по последнему 3-му изданию
(Петин В.А.
Проекты с использованием контроллера Arduino.
3-е издание БХВ-Петербург,2019.)...
Но там также конструктор и без примера реализации в *.ino
Да еще с угловыми скобками вместо кавычек для
#include <*.h>
....
У меня на такое написание жесткий матюк - файлы, что или в самой базовой папке или в
C:\Documents and Settings\NAME_USRER\Мои документы\Arduino
угловых кавычек на моей 1.8.9 не переносят.
Воть и ..."вылущиваю методом лженаучного смыка" да перечитыванием всяко-разно книжей...
:dont_know:

Re: Котуинко

Вт июл 30, 2019 18:51:26

я не понимаю вашего подхода: если вам надо пользоваться богатыми наработками ардуинщиков, то для чего лепить свои файлы? если хотите все делать по-своему, нафига вам ардуина и ее C++?

Re: Котуинко

Вт июл 30, 2019 21:12:32

Ардуинка как рабочая платформа.
Т.е. это всего лишь разновидность МК - "микросборка с лапками".
(причем начинка оных микросборок и ассортимент применяемых в них МК весьма широк)
Следовательно ее можно использовать по собственному усмотрению в
любой собственной самоделке (а не только в предлагаемых сторонними разработчиками вариантах).
СпойлерС другой стороны большое количество библиотек подогнано под чужую схемотехнику и чужие задачи.
Чаще то модули не те, то применение несколько по иному, то схемотехника видоизмененная - и
тут возникает интересный нюёнс - отдельная группа заинтересована как раз в продвижке проектов,
рассчитанных на примитив - копипаст. Или создание рынка потребителя (отсекая самостоятельное проектирование).
Контринтерес - возможность свободной работы с подобными изделиями.

Посему - надо основательно разобраться с тем, что уже имеется в наличии и делать из имеющегося
то, что необходимо для собственных задач.
Не исключая и разумное заимствование при необходимости.
8)
Неуж-то те вопросы, что мне интересны выходят за рамки НЕОБХОДИМО-ДОСТАТОЧНОГО МИНИМУМА?
Это всего лишь обычные рутинные правила для любого компилятора.
:roll:
А залезание в дебри - это уж по мере необходимости, ежли уровень задач будет такового требовать.
:beer:
Ответить