Есть прошивка под attiny85, хочется прикрутить wifi

Здравствуйте. Если устройство на attiny85, есть к нему прошивка. Можно ли как то сделать чтоб можно была вносить настройки через wifi? Либо какойто модуль докупить либо вообще другой модуль с wifi а прошивку эту переделать под другой модуль? Или это вообще не реально?

все реально

самый правильный путь это

гуглите - ESP32

Нагуглил. Шик. А как быть с прошивкой? Она под attiny85

Дык, …

Ну я как бы ноль в этом) может какието конверторы есть?))

ну так надо быть положительным…
или перейти с Техническим Заданием, обязательно указав сумму за проект! в платный раздел…
готового вроде нечего нет…
а еще можете потратит время на обучение, и модернизировав прошивку, передавать показания через rx tx, и изменять параметры…

вам какой вариант больше нравится ?)))

Наверное первый) а вообще редактировать параметры возможно будет через wifi или это дополнительная заморочка?

зависит от прошивки, суммы оплаты, и от самих параметров, некоторые переписав прошивку можно будет менять…
если скинете предмет разговора, может и подскажут точнее…

Я хз как скинуть файлы, пишет что этот формат не поддерживается для отправки, вот закинул на какойто файлообменник

TransFiles - бесплатный файлообменник без регистрации - Страница скачивания загрузки voq67

Вот так тут принято код вставлять:

sketch_may04a.ino
#include "EEPROM.h"
#include <avr/power.h>

// переменные настройки минимума и максимума по входу и выходу газа используются только для прописывания настроек в EEPROM
//#define ONLY_EEPROM_WRITE // если нужно прописать значения (ниже 4 штуки, можно свои написать) в eeprom на этапе прошивки платы, то сначало раскоментировать эту строчку и загрузить прошику, после того как светодиод заморгает на плате, строчку коментируем и опять перезаливаем прошивку
uint16_t eepromMinIn=195;
uint16_t eepromMaxIn=825;
uint8_t eepromMinOut=62;
uint8_t eepromMaxOut=205;  

// это какие то важные две строчки
#define BUTTON_PIN 3 
#define LED_PIN 1

#define LONG_DELAY 1000/2 // тут делим да два потому что дальше ядро digispark немного "накалываем"
#define SHORT_DELAY 400/2 //
#define REG_PWM_DUTY OCR0A // макрос был введён в начале потому что непонятно было какую ногу использовать прийдётся, но так и остался

// пределы этих коэффициентов 1-128. Трогать ненадо, просто выбраны (или еще надо подобрать будет!!!) среднестатистические
#define KOEF_PRESS_STEP 21 // коэффициент влияющий на определение ускорения нажатия (уменьшаем - реакция на курок более резкая)
#define KOEF_DELAY_STEP 5 // коэффициент влияющий на задержку увеличения газа (увеличиваем - реакция на курок более резкая)

#define MASS_SIZE_AVG 8 // размеры массивов нормирования газа вход-выход, можно обойтись и без этого конечно делать прямолинейную зависимость просто, но лучше немного "прогнуть" 

// volatile просто чтобы не думать что там делает компилятор, но впринципе можно у некоторых переменных убрать
volatile struct{
    struct{
        uint16_t minIn;           
        uint16_t maxIn;
        uint8_t minOut;
        uint8_t maxOut;                    
    }setup;
    uint16_t adcIn;   
    uint16_t adcOut;
    uint8_t out;      // желаемое значение выхода с учётом только массива нормирования вход-выход 
    uint8_t outForPwm;  // выход на ШИМ после всех фильтраций
    uint16_t outFilter;     // желаемое значение выхода с учётом мгновенной фильтрации по плавности    
    uint8_t flagTicher; // флаг включения режима обучения    
    uint8_t flagDelay;                       
    uint8_t delta_delay_gaz; // потом пересчитаем     = 5
    uint16_t accel_gaz_for_delay; // потом пересчитаем  =100
}gaz; 

volatile uint8_t flagButtonClick=0; // флаг нажатия кнопки
volatile uint8_t flagMsSec=0;

volatile int8_t sDelta=-20;

volatile uint16_t massAdcIn[5];
volatile uint16_t massPwm[5];

//0,51 ms
ISR(TIM0_OVF_vect)
{
    static uint16_t tmpNumCountForAccel=0;
    static uint16_t tmpNumCountForDel=0;
    if(tmpNumCountForAccel>391){ // примерно 0.199 секунды , цикл определения скорости нажатия курка        
        tmpNumCountForAccel = 0; 
        static uint16_t tmpOldGazIn=0; 
        if(gaz.flagDelay == 0)
        {   
          if(gaz.adcIn>=tmpOldGazIn){ // наброс газа при условии завершения предыдущего цикла задержки   
              uint16_t tmp = gaz.adcIn-tmpOldGazIn; // величина увеличения заданного уровня газа за цикл замера
              //gaz.flagDelay = 0;    
              if(tmp<gaz.accel_gaz_for_delay) gaz.flagDelay = 1;
              else if(tmp<(gaz.accel_gaz_for_delay*2)) gaz.flagDelay = 2;                
              else if(tmp<(gaz.accel_gaz_for_delay*3)) gaz.flagDelay = 3;                
              else if(tmp<(gaz.accel_gaz_for_delay*4)) gaz.flagDelay = 4;                         
          }else gaz.flagDelay = 4;
        }
        tmpOldGazIn = gaz.adcIn;                       
        if(gaz.flagDelay) gaz.outFilter += gaz.delta_delay_gaz*gaz.flagDelay;  // можно конечно вставить просто функция рампы и менять задержку и всё
        else gaz.outFilter = 255;
        if(gaz.outFilter>255) gaz.outFilter = 255;                                            
    }                     

    if(tmpNumCountForDel>2){
      tmpNumCountForDel=0;
      if(gaz.outForPwm < gaz.outFilter) gaz.outForPwm++;
      else gaz.outForPwm = gaz.outFilter; 
      if(gaz.outForPwm >= gaz.out){  // это срабатывает при сбросе газа тоже и также ограничивает выход
          gaz.outForPwm = gaz.out;   
          gaz.outFilter = gaz.out;
          gaz.flagDelay=0;
      }               
    }
    tmpNumCountForDel++;
    tmpNumCountForAccel++;
}

#define FIRST_ADC_INPUT 1
#define LAST_ADC_INPUT 2
// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<REFS2) | (0<<ADLAR))

ISR(ADC_vect)
{
    static uint8_t input_index=0;
    static uint16_t massInAvg[MASS_SIZE_AVG]={0,0,0,0,0,0,0,0};
    static uint8_t indexMassInAvg=0;  
    static uint16_t massOutAvg[MASS_SIZE_AVG]={0,0,0,0,0,0,0,0};   
    static uint8_t indexMassOutAvg=0;   
    uint16_t tmpSumm=0;    
    uint8_t tmpI=0;        
    uint16_t reg=ADCW;  
    // Select next ADC input
    if(++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0;
    ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index;     
    
    switch(input_index){
        case 0:{              
            massOutAvg[indexMassOutAvg&7] = reg;
            indexMassOutAvg++;  
            for(tmpI=0;tmpI<MASS_SIZE_AVG;tmpI++) tmpSumm += massOutAvg[tmpI]; 
            gaz.adcOut = tmpSumm/MASS_SIZE_AVG;
            break;
        }
        case 1:{              
            massInAvg[indexMassInAvg&7] = reg;
            indexMassInAvg++; 
            for(tmpI=0;tmpI<MASS_SIZE_AVG;tmpI++) tmpSumm += massInAvg[tmpI];    
            gaz.adcIn = tmpSumm/MASS_SIZE_AVG;
            break; 
        }
    }                        
                
    static uint8_t sStatusButOld=0;
    static uint8_t sCountBut=0;     
    if(digitalRead(BUTTON_PIN)==0 && sStatusButOld==digitalRead(BUTTON_PIN) && flagButtonClick==0){ // момент нажатия (сразу после момента нажатия)   
        if(sCountBut == 250) flagButtonClick=1; // антидребезг
        else if(sCountBut<0xFF) sCountBut++;
    }else sCountBut=0; 
    sStatusButOld = digitalRead(BUTTON_PIN); 
    
    static uint16_t sCountMsSec=0;
    if(sCountMsSec>2500){    // todo тут было 2500, это из за коэффициента деления чёто
        flagMsSec=1;
        sCountMsSec = 0;     
    }else sCountMsSec++;
    
//    delay_us(10);    
    ADCSRA|=(1<<ADSC); // Start the AD conversion       
}

void setup() {  
    clock_prescale_set(clock_div_2); // но ядро digispark уверенно что частота в два раза больше, это надо учитывать если использовать функции библиотек которые работают со временем
    for(uint8_t ii=0;ii<sizeof(gaz);ii++) *((uint8_t*)&gaz)=0; // обнулим переменные
    pinMode(0, OUTPUT);pinMode(1, OUTPUT);
    pinMode(BUTTON_PIN, INPUT_PULLUP); // Кнопка
    pinMode(2, INPUT);pinMode(4, INPUT);pinMode(5, INPUT);
    
    // Timer/Counter 0 initialization
    // Timer Period: 0,51 ms
    TCCR0A = (1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (1<<WGM00);
    TCCR0B = (0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00); 

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK |= (1<<TOIE0);
    
    // Analog Comparator: Off
    ACSR=(1<<ACD);

    // ADC initialization
    ADMUX=FIRST_ADC_INPUT | ADC_VREF_TYPE;
    ADCSRA=(1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);                

    // помещаем значения по умолчанию в EEPROM, потом эти строчки надо закоментировать
#ifdef ONLY_EEPROM_WRITE    
    {
      uint8_t tmpE = eepromMinIn>>8;    
      EEPROM.update(100, tmpE);
      tmpE = eepromMinIn;
      EEPROM.update(101, tmpE);
      tmpE = eepromMaxIn>>8;
      EEPROM.update(102, tmpE);
      tmpE = eepromMaxIn;
      EEPROM.update(103, tmpE);    
      EEPROM.update(104, eepromMinOut);
      EEPROM.update(105, eepromMaxOut);
      while(1){
        digitalWrite(LED_PIN,1); delay(500);
        digitalWrite(LED_PIN,0); delay(200);  
      }
    }
#endif
    // считываем значения из EEPROM 
    {
      //eepromMinIn = EEPROM.read(100); eepromMinIn = eepromMinIn<<8; eepromMinIn |= EEPROM.read(100); 
      //eepromMaxIn = EEPROM.read(102); eepromMaxIn = eepromMaxIn<<8; eepromMaxIn |= EEPROM.read(103); 
      uint8_t tmpE = EEPROM.read(101); 
      eepromMinIn = EEPROM.read(100);
      eepromMinIn <<=8;
      eepromMinIn |= tmpE;
      tmpE = EEPROM.read(103); 
      eepromMaxIn = EEPROM.read(102);
      eepromMaxIn <<=8;
      eepromMaxIn |= tmpE;
      eepromMinOut = EEPROM.read(104); 
      eepromMaxOut = EEPROM.read(105); 
    }
    gaz.setup.minIn = eepromMinIn; gaz.setup.maxIn = eepromMaxIn; 
    gaz.setup.minOut = eepromMinOut; gaz.setup.maxOut = eepromMaxOut;   
    
    sei();  // включить глобальные прерывания 
            
    digitalWrite(LED_PIN,1); delay(LONG_DELAY);
    digitalWrite(LED_PIN,0);                

         
    if(digitalRead(BUTTON_PIN)==0){  
        gaz.flagTicher = 1;
        gaz.setup.minIn = 255;gaz.setup.maxIn = 10;
        for(uint8_t tmpI=0;tmpI<5;tmpI++){    // 5 раза моргнуть при заходе в настройку        
            digitalWrite(LED_PIN,1); delay(LONG_DELAY/2);
            digitalWrite(LED_PIN,0); if(tmpI!=4) delay(LONG_DELAY/2);                  
        }                  
        flagButtonClick=0;
    }else func_mass_gaz_set(); // установка массиов зависимости по газу

    flagButtonClick=0;   
}

void loop() {              
  switch(gaz.flagTicher){        
      case 1:{ // настройка минимума  курка
          gaz.out = 0;         
          REG_PWM_DUTY = 0;
          if(flagButtonClick){
              gaz.setup.minIn = gaz.adcIn;   
              digitalWrite(LED_PIN,1); delay(LONG_DELAY);
              digitalWrite(LED_PIN,0); delay(LONG_DELAY);      
              gaz.flagTicher++;  
              flagButtonClick=0;
          }
          break; 
      }
      case 2:{ //настройка максимума курка  
          gaz.out = 0;          
          REG_PWM_DUTY = 0;               
          if(flagButtonClick){   
              gaz.setup.maxIn = gaz.adcIn;  
              for(uint8_t tmpI=0;tmpI<2;tmpI++){    // 2 раза моргнуть медленно        
                  digitalWrite(LED_PIN,1); delay(LONG_DELAY);
                  digitalWrite(LED_PIN,0); if(tmpI!=1) delay(LONG_DELAY/2);                  
              }             
              gaz.flagTicher++;  
              flagButtonClick=0;
          }
          break;           
      }
      case 3:{ // настройка минимума выхода  
          uint16_t tmp = gaz.adcIn/4;  // повышаем разрешение для более лучшего подбора, смотрим когда колесо тронеться и тогда жмём кнопку, можно длить на 4, тогда чуть "жесче" ловить курок надо
          if(gaz.setup.maxIn>800) tmp /= 2;   
          REG_PWM_DUTY = tmp;   
          if(flagButtonClick){          
              REG_PWM_DUTY = 0;
              gaz.setup.minOut = tmp;  
              for(uint8_t tmpI=0;tmpI<3;tmpI++){    // 3 раза моргнуть медленно        
                  digitalWrite(LED_PIN,1); delay(LONG_DELAY);
                  digitalWrite(LED_PIN,0); if(tmpI!=2) delay(LONG_DELAY/2);                  
              }             
              gaz.flagTicher++;  
              flagButtonClick=0;         
          }    
          break;           
      }    
      case 4:{ // настройка максимума выхода и сохранение настроек в eeprom     
          uint16_t tmp = gaz.adcIn; 
          static uint8_t sTDelta=0; 
          tmp = map(tmp, gaz.setup.minIn, gaz.setup.maxIn, gaz.setup.minOut, 255);
          //if(gaz.setup.maxIn>512) tmp /= 2;    
          if(tmp>255) tmp=255;                          
          if(flagMsSec){                        
              if(gaz.adcOut>gaz.setup.maxIn){ if(sTDelta<255) sTDelta++;}
              else if(sTDelta) sTDelta--;                     
              flagMsSec=0;
          }      
          if(gaz.setup.minIn > gaz.adcIn) sTDelta = 0; // нулим поправку если курок отпущен        
          if(tmp>sTDelta) tmp -= sTDelta; // если поправка ненужна то эту строчку коментим
          REG_PWM_DUTY = tmp;   // какие то магические дейсвия, ищем максимальную скорость мотора и жмём кнопку
          if(flagButtonClick){ 
              uint8_t tmpI=0;           
              REG_PWM_DUTY = 0;
              gaz.setup.maxOut = tmp;                       
              for(tmpI=0;tmpI<10;tmpI++){    // 10 раза моргнуть быстро        
                  digitalWrite(LED_PIN,1); delay(SHORT_DELAY);
                  digitalWrite(LED_PIN,0); if(tmpI!=9) delay(SHORT_DELAY/4);                  
              } 
              func_mass_gaz_set(); // установка массивов зависимости по газу    
              eepromMinIn = gaz.setup.minIn; eepromMaxIn = gaz.setup.maxIn; 
              eepromMinOut = gaz.setup.minOut; eepromMaxOut = gaz.setup.maxOut;  
                 
              tmpI = eepromMinIn>>8;    
              EEPROM.update(100, tmpI);
              tmpI = eepromMinIn;
              EEPROM.update(101, tmpI);
              tmpI = eepromMaxIn>>8;
              EEPROM.update(102, tmpI);
              tmpI = eepromMaxIn;
              EEPROM.update(103, tmpI);    
              EEPROM.update(104, eepromMinOut);
              EEPROM.update(105, eepromMaxOut);
        
              gaz.flagTicher=0;  
              flagButtonClick=0;
          }   
          break;           
      }     
      default:{ // обычная работа  
      //    static int8_t sDelta=0;
          if(gaz.adcIn>gaz.setup.minIn){ 
              if(gaz.adcIn>(gaz.setup.maxIn+100)) gaz.out = gaz.setup.minOut; // защита от сильно большого значения, вещь сомнительная потому что бывают шпарят наводки (дуалтроны например) и эти превышения норма
              else if(gaz.adcIn>gaz.setup.maxIn) gaz.out = gaz.setup.maxOut; // защита от небольшого преувеличения      
              else{               
                  // линейно интерполируем  
                  unsigned char tmpI=0;
                  for(tmpI=0;tmpI<4;tmpI++) if(gaz.adcIn<=massAdcIn[tmpI]) break;                                
                  if(tmpI>4) gaz.out = massPwm[4];
                  else if(tmpI==0) gaz.out = massPwm[0];  // вообще ненужное условие    
                  else{              
                      unsigned int tmp1 = massPwm[tmpI] - massPwm[tmpI-1];
                      unsigned int tmp2 = gaz.adcIn-massAdcIn[tmpI-1];    
                      tmp1 *= tmp2; 
                      tmp2 = massAdcIn[tmpI] - massAdcIn[tmpI-1];
                      tmp1 /= tmp2;
                      tmp2 = massPwm[tmpI-1];         
                      gaz.out = tmp2 + tmp1;
                  }                     
              }
              if(sDelta>0) sDelta=0;                          
          }else{                           
              if(flagMsSec){                        
                  if(gaz.adcIn>gaz.adcOut) sDelta++;
                  else if(gaz.adcIn<gaz.adcOut) sDelta--; 
                  if(sDelta>0) sDelta=0;
                  else if(sDelta<-35) sDelta = -35;
                  if(abs(sDelta)>gaz.setup.minIn && sDelta<0) sDelta = -gaz.setup.minIn;
                  flagMsSec=0;
              }
              int16_t tmpGaz = gaz.setup.minOut;
              tmpGaz += sDelta;
              if(tmpGaz<0) tmpGaz=0;
              gaz.out =  tmpGaz; // калибруем    
          }     
          REG_PWM_DUTY = gaz.outForPwm;      
      }  
  }  
}

void func_mass_gaz_set(){
                                         
    // чуть прогибаем кривую зависимости сигнал курка газа - реальный выход газа на контроллер, но не сильно
    massAdcIn[0] = gaz.setup.minIn;
    massAdcIn[4] = gaz.setup.maxIn; 
    massAdcIn[2] = (gaz.setup.minIn+gaz.setup.maxIn)/2;   
    massAdcIn[1] = (massAdcIn[0] + massAdcIn[2])/2; 
    massAdcIn[3] = (massAdcIn[2] + massAdcIn[4])/2; 

    massPwm[0] = gaz.setup.minOut;
    massPwm[4] = gaz.setup.maxOut; 
    massPwm[2] = (gaz.setup.minOut+gaz.setup.maxOut)/2;  
    massPwm[2] *= 110; //
    massPwm[2] /=128; // 
    massPwm[1] = (massPwm[0] + massPwm[2])/2;    
    massPwm[1] *= 119; //
    massPwm[1] /=128; // 
    massPwm[3] = (massPwm[2] + massPwm[4])/2;   
    massPwm[3] *= 124; //
    massPwm[3] /=128; //   
    
    gaz.accel_gaz_for_delay = ((gaz.setup.maxIn - gaz.setup.minIn)*KOEF_PRESS_STEP)/128; // нашли шаг ускорения нажатия курка штоли     
    
    gaz.delta_delay_gaz = ((gaz.setup.maxOut - gaz.setup.minOut)*KOEF_DELAY_STEP)/128; // нашли шаг прибавления задержки
}
EEPROM.h
/*
  EEPROM.h - EEPROM library
  Original Copyright (c) 2006 David A. Mellis.  All right reserved.
  New version by Christopher Andrews 2015.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef EEPROM_h
#define EEPROM_h

#include <inttypes.h>
#include <avr/eeprom.h>
#include <avr/io.h>

/***
    EERef class.
    
    This object references an EEPROM cell.
    Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
    This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
***/

struct EERef{

    EERef( const int index )
        : index( index )                 {}
    
    //Access/read members.
    uint8_t operator*() const            { return eeprom_read_byte( (uint8_t*) index ); }
    operator uint8_t() const             { return **this; }
    
    //Assignment/write members.
    EERef &operator=( const EERef &ref ) { return *this = *ref; }
    EERef &operator=( uint8_t in )       { return eeprom_write_byte( (uint8_t*) index, in ), *this;  }
    EERef &operator +=( uint8_t in )     { return *this = **this + in; }
    EERef &operator -=( uint8_t in )     { return *this = **this - in; }
    EERef &operator *=( uint8_t in )     { return *this = **this * in; }
    EERef &operator /=( uint8_t in )     { return *this = **this / in; }
    EERef &operator ^=( uint8_t in )     { return *this = **this ^ in; }
    EERef &operator %=( uint8_t in )     { return *this = **this % in; }
    EERef &operator &=( uint8_t in )     { return *this = **this & in; }
    EERef &operator |=( uint8_t in )     { return *this = **this | in; }
    EERef &operator <<=( uint8_t in )    { return *this = **this << in; }
    EERef &operator >>=( uint8_t in )    { return *this = **this >> in; }
    
    EERef &update( uint8_t in )          { return  in != *this ? *this = in : *this; }
    
    /** Prefix increment/decrement **/
    EERef& operator++()                  { return *this += 1; }
    EERef& operator--()                  { return *this -= 1; }
    
    /** Postfix increment/decrement **/
    uint8_t operator++ (int){ 
        uint8_t ret = **this;
        return ++(*this), ret;
    }

    uint8_t operator-- (int){ 
        uint8_t ret = **this;
        return --(*this), ret;
    }
    
    int index; //Index of current EEPROM cell.
};

/***
    EEPtr class.
    
    This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
    Just like a normal pointer type, this can be dereferenced and repositioned using 
    increment/decrement operators.
***/

struct EEPtr{

    EEPtr( const int index )
        : index( index )                {}
        
    operator int() const                { return index; }
    EEPtr &operator=( int in )          { return index = in, *this; }
    
    //Iterator functionality.
    bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
    EERef operator*()                   { return index; }
    
    /** Prefix & Postfix increment/decrement **/
    EEPtr& operator++()                 { return ++index, *this; }
    EEPtr& operator--()                 { return --index, *this; }
    EEPtr operator++ (int)              { return index++; }
    EEPtr operator-- (int)              { return index--; }

    int index; //Index of current EEPROM cell.
};

/***
    EEPROMClass class.
    
    This object represents the entire EEPROM space.
    It wraps the functionality of EEPtr and EERef into a basic interface.
    This class is also 100% backwards compatible with earlier Arduino core releases.
***/

struct EEPROMClass{

    //Basic user access methods.
    EERef operator[]( const int idx )    { return idx; }
    uint8_t read( int idx )              { return EERef( idx ); }
    void write( int idx, uint8_t val )   { (EERef( idx )) = val; }
    void update( int idx, uint8_t val )  { EERef( idx ).update( val ); }
    
    //STL and C++11 iteration capability.
    EEPtr begin()                        { return 0x00; }
    EEPtr end()                          { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
    uint16_t length()                    { return E2END + 1; }
    
    //Functionality to 'get' and 'put' objects to and from EEPROM.
    template< typename T > T &get( int idx, T &t ){
        EEPtr e = idx;
        uint8_t *ptr = (uint8_t*) &t;
        for( int count = sizeof(T) ; count ; --count, ++e )  *ptr++ = *e;
        return t;
    }
    
    template< typename T > const T &put( int idx, const T &t ){
        EEPtr e = idx;
        const uint8_t *ptr = (const uint8_t*) &t;
        for( int count = sizeof(T) ; count ; --count, ++e )  (*e).update( *ptr++ );
        return t;
    }
};

static EEPROMClass EEPROM;
#endif

Еще один самоубийца с газом поиграть решил… ))

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

так, 25% дела сделано, теперь вам надо объяснить что там менять ?

Автор кода выложил это все на всеобщее обозрение. Он как бы и так это бесплатно сделал , дергать его такими вопросами не охота да и врядли он ответит, таких как я с глупыми вопросами у него наверное достаточно)

Да, с газом очень хочется поиграться потому что купленная плата упг не решила вопрос на этой самочборной шляпе)

Да я хх, просто идея возникла как то wifi прикрутить, но я думал там както попроще это все, attiny85 я заказал, попробую сначала на ней сделать может еще у меня мозгов и не хватит ее прошить

бывает и такое… за такое ТЗ без точного указания того что нужно, надо сразу скидку делать… 80% тогда вы переводите 30.000 и я может что то сделать там смогу, сам подумаю, посмотрю, верно ?))))

))) вот это расценки у программистов) я подумаю) буду думать долго, бесконечно долго)) а если серьезно у автора этой прошивки есть приблуды по 4500 которые точно решат мою проблему, буду покупать если меня не устроит этот бесплатный вариант)

то что они есть, не значит что столько платят, так что если решили сами все освоить, то в принципе полезно, но не факт что будите зарабатывать…)))
ладно думайте!)))

Да какие заработки, мне бы прошить то что есть) телефоны я шил раньше когда кнопочные еще были) программатор даже был для прошивки специальный но с тех пор много времени прошло да и я уже не торт) чем хоть эту антуту шить подскажите забесплатно)

не вникал в проект… будем надеяться что памяти там хватит, и если не ошибаюсь как вы относитесь к готовой отладочной плате ATTINY85 ?
https://aliexpress.ru/item/1005008375421451.html вроде прошивается по usb…

Дак я такую и заказал, прошивается по юсб а вот прога какая хз, там про прошивку вообще ни слова в этом паблике. Я так понимаю нужна программа arduino ide. Еще у меня есть usbasp за 160 деревянных)