• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Analiza programu, problem z naliczaniem zmiennej.
#1
Cześć
Mam problem. Zbudowałem zaciągnięty ze strony:
https://www.instructables.com/How-to-Bui...Computer-/
Trochę przerobiony, bo nie ma RTC, inny (mniejszy) oled, inny pomiar temperatury.
Jest tam parę zmian. Ale reszta, główna cześć programu jest taka sama. Problem jaki mnie trapi to naliczanie prędkości. Od ok 93km/h LCD sie zawiesza, na moment wskakuje wartość prędkości coś ok 6340. Gdy zwolnię samochodem poniżej 93km/h to wszystko wraca do normy. Prędkość to zmienna "speed1". Gdy jest "zwieszony" nalicza tylko dystans, nie jest naliczane żużycie paliwa (LPG i PB), nie reaguje na przyciski, tak jakby tylko wchodził w przerwanie od dystansu i prędkości. Działał poprawnie do momentu gdy nie zmieniłem czujnika obrotów koła. Wpiąłem sygnał ze skrzyni biegów, wcześniej był kontaktron i magnes. Gdy ustaliłem stałą na "impuls" dystansu to zaczął się cyrk. Na aktualną chwile nie mam jak tego debugować, bo mam krótki przewód usb. W poniedziałek zakupie dłuższy. 


Kod:
// 29 zmienna dla LPG
// 207 przerwania
// 311 menu
// 610 dystans


// Libraries
#include "PinChangeInterrupt.h" // enables the interrupts at the other pin except the ones at the digital pins 2 and 3
#include <avr/sleep.h>          // enables the sleep function
#include <avr/power.h>          // power management
#include <EEPROMex.h>           // enables some special functions for writing to and reading from EEPROM
#include <EEPROMVar.h>
#include <Wire.h>               // IIC LIBRARY
#include <math.h>               // enables complex math functions
#include <Adafruit_SSD1306.h>   // library for the OLED and graphics
#include <Adafruit_GFX.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS A2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress outside;

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

// variables declaration
//        279.1    x
//        323.3 466062

volatile static float vss_pulse_distance = 0.000402344;   // coefficient -- change this according to your
volatile static float vss_pulse_distance1 = 0.000040234;
//        1201     ok?
//        1283     47
//        1119     37.5
volatile float LPG_injector_flow = 1151e-11;
volatile static float unleadedFlow = 1743e-11;            // gasoline injector flow coef. -- change this according to your measurements (litres/microseconds)

byte LPG1, LPG2, LPG3, LPG4, digitLPG, pos = 0;
volatile unsigned long vss_pulses;
volatile float traveled_distance, traveled_distance2, traveled_distance3, traveled_distance4, seconds_passed, speed1, avg_speed, distance_to_LPGstation;
volatile float used_LPG, used_LPG2, instant_LPG_consumption, avg_LPG_consumption, LPG_in_tank, Full_tank = 45 ;
volatile float  srednieLPG , chwilowe, dystans, sredniePB, zasieg, zostaloLPG, poziomLPG;
volatile float used_Unleaded, used_Unleaded2;
volatile float average_L_100km_Unlead;

volatile unsigned long unleadTime1 = 0, unleadTime2 = 0, unleadinj_Open_Duration = 0;
volatile unsigned long LPG_injector_open_duration = 0, injTime1 = 0, injTime2 = 0;
int postemp;
int vss_pin = 2; // VSS signal input at digital pin 2 (INT0)
int LPG_pin = 3; // LPG injector signal input at digital pin 3 (INT1)
int ignition_pin = 9; // ignition signal input
int unleaded_pin = 12; // Unleaded injector signal input
int analogPin = A3; // poziom paliwa
int LED = 13;
float tempC;
int analog;


boolean buttonState, buttonState2;
boolean lastButtonState2 = HIGH;
long lastDebounceTime = 0, logohold, counter, counter2;
volatile boolean ignition = true;
boolean ignoreRelease = false;
boolean inst_disp = true;
byte menunumber = 0,  menunumbermax = 10;
boolean timeRead = false, displaychange = true;
float thermReading, steinhart;
boolean dots = true;
//int poziom = 0;
int temperatura;



#define NUMSAMPLES 5
#define BCOEFFICIENT 3630

int samples[NUMSAMPLES];
int i = 0;


void setup()
{
  /// temperatura
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // locate devices on the bus
  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: ");
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");
  if (!sensors.getAddress(outside, 0)) Serial.println("Unable to find address for Device 0");
  Serial.print("Device 0 Address: ");
  //  printAddress(outside);
  Serial.println();

  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(outside, 9);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(outside), DEC);
  Serial.println();




  pinMode(10, INPUT); // Button 2
  pinMode(11, INPUT); // Button 1
pinMode(13, OUTPUT);  // LED
  pinMode(vss_pin, INPUT);
  pinMode(LPG_pin, INPUT);
  pinMode(ignition_pin, INPUT);
  pinMode(unleaded_pin, INPUT);

  // below recalls the values stored in case of power loss
  traveled_distance = EEPROM.readFloat(0);
  traveled_distance2 = EEPROM.readFloat (5);
  used_LPG = EEPROM.readFloat (10);
  used_LPG2 = EEPROM.readFloat(15);
  LPG_in_tank = EEPROM.readFloat(20);
  seconds_passed = EEPROM.readFloat(25);
  used_Unleaded = EEPROM.readFloat(30);
  traveled_distance3 = EEPROM.readFloat (35);
  used_Unleaded2 = EEPROM.readFloat(45);
  traveled_distance4 = EEPROM.readFloat (50);
  // LPG1 = EEPROM.readByte (40);
  // LPG2 = EEPROM.readByte (41);
  // LPG3 = EEPROM.readByte (42);
  // LPG4 = EEPROM.readByte (43);
  //LPG_injector_flow = 1043e-11;

  noInterrupts();
  // set and initialize the TIMER1
  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // set entire TCCR1B register to 0
  TCCR1B |= (1 << CS12);
  TIMSK1 |= (1 << TOIE1);
  TCNT1 = 3036;

  attachPCINT(digitalPinToPinChangeInterrupt(ignition_pin), ignitionSignal, CHANGE);

  interrupts();
  delay(10);
  // Serial.begin(9600);
}

void loop()
{ // When the ignition switch is turned, executes the next two ifs
  Serial.println("petla glowna");
  if (ignition == true and digitalRead(9) == LOW)


  {
    //Serial.println("pin9_LOW");
    //Serial.println(menunumber);
    detachInterrupt(digitalPinToInterrupt(vss_pin));
    detachInterrupt(digitalPinToInterrupt(LPG_pin));
    detachPCINT(digitalPinToPinChangeInterrupt(unleaded_pin));
    delay(50);
    ignition = false;
    digitalWrite (LED, LOW);

    //       when the ignition switched off it stores the values to the EEPROM
    EEPROM.writeFloat (0, traveled_distance);
    EEPROM.writeFloat (5, traveled_distance2);
    EEPROM.writeFloat (10, used_LPG);
    EEPROM.writeFloat (15, used_LPG2);
    EEPROM.writeFloat (20, LPG_in_tank);
    EEPROM.writeFloat (25, seconds_passed);
    EEPROM.writeFloat (30, used_Unleaded);
    EEPROM.writeFloat (35, traveled_distance3);
    EEPROM.writeFloat (45, used_Unleaded2);
    EEPROM.writeFloat (50, traveled_distance4);

    display.ssd1306_command(SSD1306_DISPLAYOFF);
    //  Serial.println("sleep");
    sleep_enable(); // enables the sleep mode
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set the sleep mode
    cli();
    sleep_bod_disable(); // disables the brown out detector to consume less power while sleeping
    sei();
    sleep_mode(); // microcontroller goes to sleep
  }
  //  // when it wakes up continues from here -- also the first time we turn the ignition key to ON starts from here
  if (ignition == true && digitalRead(9) == HIGH)
  {
    Serial.println("pin9_HIGH");
    ignition = false;    // this variable is needed in order to run once the code inside this if
    logohold = millis(); // hold the LOGO screen on, for 2 sec
    inst_disp = true;
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.clearDisplay();
    display.setCursor(15, 10);
    display.setTextSize(2);
    display.print("FORESTER");
    display.display();
    digitalWrite (LED, HIGH);

    attachInterrupt(digitalPinToInterrupt(vss_pin), distance, RISING); // attaches the interrupt which related to the VSS signal
    attachInterrupt(digitalPinToInterrupt(LPG_pin), LPG_injector_time, CHANGE); // interrupt for LPG injector signal
    attachPCINT(digitalPinToPinChangeInterrupt(unleaded_pin), UnleadedTime, CHANGE); // petrol injector signal input and interrupt
    while (millis() - logohold < 3000) ;


  }

  // every 5sec calculates average LPG consumption, remaining distance accordingly to the calculated remaining fuel in tank, average speed and average Unleaded cons.
  if (millis() % 5000 < 50)
  {
    avg_LPG_consumption = 100 * used_LPG2 / traveled_distance2;
    distance_to_LPGstation = 100 * LPG_in_tank / avg_LPG_consumption;
    avg_speed = (traveled_distance3 / seconds_passed) * 3600;
    average_L_100km_Unlead = 100 * used_Unleaded2 / traveled_distance2;
    analog = analogRead(A6);
  }

  // For the short and long press function I consulted: http://jmsarduino.blogspot.gr/2009/05/click-for-press-and-hold-for-b.html
  // There are many differences though
  // "button 1" -- only  SHORT PRESS function -- changes occur on press, because there is no LONG PRESS function
  if (digitalRead(10) != buttonState) {
    buttonState = digitalRead(10);
    // Serial.println("pin11_low");
    if (buttonState == LOW)
    {
      if (menunumber <= menunumbermax) { // changes the display indications forwards
        if (menunumber == menunumbermax) menunumber = 0;
        else menunumber += 1;
      }
    }
  }

  ////////// "button 2" functions /////////////////
  buttonState2 = digitalRead(11);
  if (buttonState2 == LOW && lastButtonState2 == HIGH) lastDebounceTime = millis(); //keeps the time that button2 pressed

  if (buttonState2 == HIGH && lastButtonState2 == LOW)
  {
    if (ignoreRelease == false) // "button 2" SHORT PRESS functions -- on release
    {
      if (menunumber <= menunumbermax)
      { if (menunumber == 0) menunumber = menunumbermax;
        else menunumber = menunumber - 1;
      }
    }
    else ignoreRelease = false;
  }
  //////////////////// "button 2" LONG PRESS functions /////////////////////////////////////////////////////
  if (digitalRead(10) == HIGH) displaychange = true;
  if (buttonState2 == LOW && (millis() - lastDebounceTime) > 3000 && displaychange == true) // below are the long press functions for button 2
  {
    if (menunumber == 0) traveled_distance2 = 0,LPG_in_tank = Full_tank, used_LPG2 = 0, traveled_distance = 0, avg_LPG_consumption = 0, used_Unleaded2 = 0, used_LPG = 0; //kasowanie po tankowaniu
    if (menunumber == 1) traveled_distance2 = 0, avg_LPG_consumption = 0 ;// kasowanie sredniego lpg
    if (menunumber == 3) traveled_distance3 = 0, seconds_passed = 0, avg_speed = 0; // kasowanie sredniej predkosci
    if (menunumber == 4) traveled_distance = 0; //trip
    if (menunumber == 6) used_LPG = 0; // kasowanie zuztego lpg
    if (menunumber == 7) LPG_in_tank = Full_tank; // Tankowanie
    if (menunumber == 8) average_L_100km_Unlead = 0;//Kasowanie sredniego PB
    if (menunumber == 2) traveled_distance2 = 0, used_LPG2 = 0, avg_LPG_consumption = 0, used_Unleaded2 = 0; // same with menunumber = 1
    if (menunumber == 9) used_Unleaded = 0; // total unleaded fuel reset

    ignoreRelease = true;
  }
  lastButtonState2 = buttonState2;
  //menunumber = 0;
  (menunumber);
chwilowe = instant_LPG_consumption;
srednieLPG = avg_LPG_consumption;

  //Serial.println(poziom);

Serial.println(menunumber);
  // below are the misc screens
  switch (menunumber)
  {
    case 1:
cons1:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setTextSize(1);
      display.setCursor(2, 23);
      display.print("Srednie LPG L/100KM");
      display.setCursor(40, 0);
      display.setTextSize(3);
      if (isnan(srednieLPG) || isinf(srednieLPG)) display.print(F("---"));
      else display.print(srednieLPG, 1);
      display.display();
      break;

    case 0:

        display.clearDisplay();
        if(inst_disp == true) displaychange = false, inst_disp = false, digitLPG = 0, pos = 0;
        display.setTextColor(WHITE);
        display.setCursor(19 , 23);
        display.setTextSize(1);
        if (distance_to_LPGstation < 10 ||  isnan(distance_to_LPGstation) || isinf(distance_to_LPGstation) ) display.print(F("---"));
        else display.print(distance_to_LPGstation, 0);
        display.setCursor(93,23);
        display.setTextSize(1);
//        if (speed1 > 2) display.print(F("L/100"));
//        else display.print(F("L/H")); //when the car is stopped displays the instant consumption in l/h
        display.print(srednieLPG, 1);
        display.setCursor(40,0);
        display.setTextSize(3);
        if(chwilowe > 99.9) display.print(F("--.-"));
        else display.print(chwilowe,1);
        display.display();
      break;

    case 2:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setCursor(40, 0);
      display.setTextSize(3);
      display.print(speed1, 0);
      display.setCursor(25, 24);
      display.setTextSize(1);
      display.print(F("PREDKOSC KM/H"));
      display.display();
      break;

    case 3:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setCursor(40, 0);
      display.setTextSize(3);
      display.print(avg_speed, 0);
      display.setCursor(10, 24);
      display.setTextSize(1);
      display.print(F("SREDNIA PRED. KM/H"));;
      display.display();
      break;

    case 4:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setCursor(19, 24);
      display.setTextSize(1);
      display.print(F("PRZEBYTE KM"));
      display.setCursor(35, 0);
      display.setTextSize(3);
      display.print(traveled_distance, 1);
      display.display();
      break;

    case 5:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setCursor(40, 0);
      display.setTextSize(3);
      if (distance_to_LPGstation < 10 ||  isnan(distance_to_LPGstation) || isinf(distance_to_LPGstation) ) display.print(F("---"));
      else display.print(distance_to_LPGstation, 0);
      display.setTextSize(1);
      display.setCursor(25, 24);
      display.print(F("ZASIEG KM"));
      display.display();
      break;

    case 6:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setCursor(34, 24);
      display.setTextSize(1);
      display.print(F("ZUZYTE LPG"));
      display.setCursor(40, 0);
      display.setTextSize(3);
      display.print(used_LPG, 1);
      //display.print(F("l"));
      display.display();
      break;

    case 7:
      display.clearDisplay();
      //Serial.println("case_7");
      display.setTextColor(WHITE);
      //display.drawBitmap(31, 0,  FuelTank, 64, 32, WHITE);
      display.setCursor(40, 0);
      display.setTextSize(3);
      if (LPG_in_tank <= 0 ) display.print(F("0.0"));
      else display.print(LPG_in_tank, 1);
      display.setTextSize(1);
      display.setCursor(19, 24);
      display.print(F("ZOSTALO LPG L"));
      display.display();
      break;

    case 8:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setCursor(10, 24);
      display.setTextSize(1);
      display.print("SREDNIE PB L/100KM");
      display.setCursor(40, 0);
      display.setTextSize(3);
      if (isnan(average_L_100km_Unlead) || isinf(average_L_100km_Unlead)) display.print(F("---"));
      else display.print(average_L_100km_Unlead, 1);
      display.display();
      break;
    case 9:
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.setTextSize(1);
      display.setCursor(37, 24);
      display.print(F("ZUZYTE PB"));
      display.setCursor(40, 0);
      display.setTextSize(3);
      display.print(used_Unleaded, 1);
      display.display();
      break;
    case 10:
      display.clearDisplay();
      sensors.requestTemperatures();
      float tempC = sensors.getTempCByIndex(0);
      display.setTextColor(WHITE);
      display.setCursor(20, 0);
      display.setTextSize(2);
      display.print(tempC, 1);
      display.setTextSize(2);
      display.setCursor(100, 0);
      display.print(F("oC"));
      float napiecie = analog * 0.01515 ;
      display.setCursor(20, 14);
      display.setTextSize(2);
      display.print(napiecie, 2);
      display.setCursor(100, 14);
      display.print(F("V"));
      display.display();
      break;


      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      // the following are secondary displays and activated only in case we want to set the LPG Coef.(case 11) or the Time (case 12)




  }
  //Serial.println("koniec case");
}

ISR(TIMER1_OVF_vect) //TIMER1 overflow interrupt -- occurs every 1sec --
{
  instantSpeed();

  LPG_Consumption();
  LPG_injector_open_duration = 0;

  unleadedConsumption();
  unleadinj_Open_Duration = 0;

  seconds_passed++;
  vss_pulses = 0;

  TCNT1 = 3036;
}

void distance()
{
  Serial.println("void distance");
  vss_pulses++;
  traveled_distance += vss_pulse_distance;
  traveled_distance2 += vss_pulse_distance;
  traveled_distance3 += vss_pulse_distance;
  traveled_distance4 += vss_pulse_distance;
  // we calculate 3 times the same thing in order to reset the distance, the average cons. and average speed independently
}

void instantSpeed()
{
  Serial.println("void predkosc");
  speed1 = (vss_pulse_distance1 * vss_pulses * 3600)*10;
  //Serial.println(speed);
  //Serial.println("predkosc");
  //if (speed > 160) speed = 160;
  //Serial.println(speed);
  //Serial.println("predkosc2");
}

// The following routine is giving the way to calculate the total time that LPG injector open during the 1sec interval
void LPG_injector_time()
{
  injTime2 = micros();
  if ((injTime2 - injTime1) < 5000 && (injTime2 - injTime1) > 4)
  {
    LPG_injector_open_duration = LPG_injector_open_duration + injTime2 - injTime1;
  }
  injTime1 = injTime2;
}


void LPG_Consumption()
{
  Serial.println("LPG zuzycie");
  if (speed1 > 2 ) instant_LPG_consumption = (100 * ((LPG_injector_open_duration * LPG_injector_flow) * 3600)) / speed1;

  else  instant_LPG_consumption = LPG_injector_open_duration * LPG_injector_flow * 3600; // when the car stops calculates the instant consumption in l/h

  used_LPG = used_LPG + (LPG_injector_open_duration * LPG_injector_flow);
  used_LPG2 = used_LPG2 + (LPG_injector_open_duration * LPG_injector_flow);
  LPG_in_tank = LPG_in_tank - (LPG_injector_open_duration * LPG_injector_flow);
}

void UnleadedTime() // it is called every time a change occurs at the gasoline injector signal and calculates gasoline injector opening time, during the 1sec interval

{
  if (digitalRead(12) == LOW)
  {
    unleadTime1 = micros();
  }
  if (digitalRead(12) == HIGH)
  {
    unleadTime2 = micros();
  }
  if (unleadTime2 > unleadTime1)
  { if ((unleadTime2 - unleadTime1) > 500 && (unleadTime2 - unleadTime1) < 12000) // some conditions to avoid false readings because of noise

    {
      unleadinj_Open_Duration = unleadinj_Open_Duration + (unleadTime2 - unleadTime1); //total useconds that the gasoline injector opens throughout 1sec
    }
  }
}

void unleadedConsumption()
{
  used_Unleaded = used_Unleaded + (unleadinj_Open_Duration * unleadedFlow);
  used_Unleaded2 = used_Unleaded2 + (unleadinj_Open_Duration * unleadedFlow);
  Serial.print("PB");
}


void ignitionSignal() // this is called everytime the ingintion signal changes -- if the microcontroller is in sleep mode, it will wake up
{
  ignition = !ignition;
}

void printTemperature(DeviceAddress deviceAddress)
{
  // method 1 - slower
  //Serial.print("Temp C: ");
  //Serial.print(sensors.getTempC(deviceAddress));
  //Serial.print(" Temp F: ");
  //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit

  // method 2 - faster
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == DEVICE_DISCONNECTED_C)
  {
    Serial.println("Error: Could not read temperature data");
    return;
  }
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}
 
Odpowiedź
#2
Za dużo floatów i za dużo przerwań, procek nie daje rady. Jedyna metoda albo z tym żyć albo wszystko do przerobienia...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
Możesz kupić sobie inne Arduino z zegarem 20MHz lub jakiś przetaktowany powyżej 20MHz, zakres prędkości powinien się zwiększyć proporcjonalnie. Niektóre funkcje Arduino mogą nie działać prawidłowo.
Wywal z obliczeń w przerwaniach wszystko co ma float, zamiast liczyć XXX.YYY km zliczaj m. Tu trzeba przeanalizować cały tok obliczeń, od przyjętych stałych aż po wynik, wybrać zakres zmiennej najmniejszy jaki jest możliwy by nie doszło do jej przepełnienia, a obliczenia prowadzić tak by 1000x1000/1000 zamienić na (1000/1000)*1000, to zmniejsza liczby, ale można utracić informacje.
Może nawet jakieś dodanie kodu przyspieszyć działanie przerwań, czyli w loop liczysz sobie siermiężnie na float, ale dane do zsumowania w przerwaniu przeliczasz na m czy nawet mm (tu liczba 32 bity bez znaku wystarczy tylko na 4000 km) i jako liczbę całkowitą tam wrzucasz by ją sumować z zapisaną. Potem znowu przy odczycie zapisujesz do zmiennej float by ją wyświetlić na ekranie. W sumie zejdzie dłużej, ale w przerwaniu krócej.
Tak dla porównania, ESP32 dodaje long i float w tym samym czasie 0.08us, Atmega32 16MHz dodaje long w 2us, float w 10us, już to przyspieszyło by to przerwanie w dodawaniem floatów x5. Wymiana uC na ESP32 przyspieszyłaby bardziej, ale dużo więcej byłoby do przerobienia. Jak w AVR zamienisz liczbę 32bity na 16 bity to znowu będzie 2x szybciej.
W drugim przerwaniu wywoływana jest funkcja micros(), to też rujnuje jego czas wykonania, jest jeszcze gorzej. Jak nie wystarczy odchudzenie pierwszego przerwania to tu też trzeba powalczyć, a może przede wszystkim tu.
W każdym przerwaniu możesz dodać zmianę stanu jakiegoś pinu na czas trwania przerwania (na rejestrach, by to był pojedynczy cykl zegara), podłączyć oscyloskop i poobserwować ile impulsów jest w stanie zliczyć.
 
Odpowiedź
#4
Dzięki.
W zasadzie z jedną rzeczą poradziłem sobie, już nalicza mi dobrze prędkość, rozbiłem jedno działanie na parę mniejszych, ale znów gdzie indziej pojawił się problem. Teraz średnie spalanie źle zlicza.

Ok dzięki już wiem gdzie jest problem. Biore się do roboty.

Mam jeden ESP32 ale właśnie boli mnie to że kupe programu trzeba by przerobić. Nie jestem na tyle jeszcze biegły aby to bez "bólu" sobie zrobić. Jak zauważyłem też to nano nie jest w pełni kompatybilne z niby pasującym ESP.
 
Odpowiedź
#5
Da sie to zrobić na atmega328p, ale ktoś miał fantazje...

Zrób kilka zasad pozbądź sie floatów tylko liczby całkowite, i przerwania jak najszybsze a dużego kopa dasz mu i bedzie wszystko fruwać...


"Potem znowu przy odczycie zapisujesz do zmiennej float by ją wyświetlić na ekranie. W sumie zejdzie dłużej, ale w przerwaniu krócej"

Da się liczbę całkowita wyświetlić jako float, po prostu prosta zasada 0.002 to to samo co 2 z tym że wyświetlanie trzeba przyjąć że 2 to "2 tysięczne" użyć tablicy i ułożyć od tyłu poleceniem for a wyświetlić tablicę...

data = 2
tab[6]

for (i_ = 6; i_ > 0; Data/= 10, i_--) {
tab[i_ - 1] = (Data % 10)+0x30;
}

tab[0] = tab[1]
tab[1] = tab[2]
tab[3] = "."


zapis do tablicy od tyłu da nam

00.002

proste? i bez floata
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#6
Nie proste dla mnie, ale bez float. Dzięki
 
Odpowiedź
#7
Trochę poprawiłem ale zastanawia mnie jedno. Lepiej do zmiennej zapisać jedno działanie z mnożeniem dzieleniem z 4 zmiennych.
Czy rozbić to na parę równań?
Np lepsze?
Z= (x * y * b)/3000
Czy
Z = (x* y * b)
Z1 = Z /3000

Co zajmuje mniej czasu?
 
Odpowiedź
#8
Bez znaczenia
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#9
Dzięki
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości