orgua / OneWireHub

OneWire slave device emulator
GNU General Public License v3.0
343 stars 86 forks source link

Not Run Correctly on STACK-M5 ATOM-U (ESP32) #132

Closed gegedvd closed 10 months ago

gegedvd commented 10 months ago

Hello , my software get sensor info by type on Serial to return A = Get MLX90614 Ambiant B = Get MLX90614 Ir Temp C = Get BMP388 Temp D = Get BMP388 Pressure E = Get DS18B20 Temp S20/S50/S25 = Set Temp Of simulated DS18B20 R = RESTART

i have compiling error in arduino and platformio

...\2.0.11\cores\esp32/Arduino.h:88:67: error: call to non-'constexpr' function 'uint32_t getCpuFrequencyMhz()'
 #define clockCyclesPerMicrosecond() ( (long int)getCpuFrequencyMhz() )
...\2.0.11\cores\esp32/Arduino.h:90:46: note: in expansion of macro 'clockCyclesPerMicrosecond'
 #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )

I fixed this error in arduino.h

i have replace this

#define clockCyclesPerMicrosecond() ( (long int)getCpuFrequencyMhz() )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )

by this (see in other issue)

#define clockCyclesPerMicrosecond() ((uint16_t)(F_CPU / 1000000L))
#define clockCyclesToMicroseconds(a) ((uint32_t)((a) / clockCyclesPerMicrosecond()))
#define microsecondsToClockCycles(a) ((uint32_t)((a) * clockCyclesPerMicrosecond()))

once corrected there is no more compilation error but OneWireSlave does not work my code user thanks a lot for our help

#include <Adafruit_MLX90614.h>  //Adafruit mlx90614
#include <Adafruit_BMP3XX.h>    //Adafruit BMP3XX
#include "OneWire.h"
#include "OneWireHub.h"
#include "DS18B20.h"  // Digital Thermometer, 12bit

constexpr uint8_t pin_led{ 12 };
constexpr uint8_t pin_onewiresim{ 33 };
constexpr uint8_t pin_onewire{ 25 };

void(* reboot) (void) = 0;

auto hub = OneWireHub(pin_onewiresim);

auto ds18b20 = DS18B20(DS18B20::family_code, 0x00, 0x00, 0xB2, 0x18, 0xDA, 0x00);  // DS18B20: 9-12bit, -55 -  +85 degC

Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_BMP3XX bmp = Adafruit_BMP3XX();

OneWire oneWire(pin_onewire);

void GetTempDs(void);
int Recvfunc();

void setup() {

  Serial.begin(115200);
  Serial.println("EVO_INTERFACE_BOARD_V1.0");
  Serial.print("Upload : ");
  Serial.print(__DATE__);
  Serial.print(" ");
  Serial.println(__TIME__);
  Serial.println("Initializing");
  Serial.print("init mlx = ");
  Serial.println(mlx.begin() ? "Ok" : "Nok");
  Serial.print("init bmp = ");
  Serial.println(bmp.begin_I2C(0x77) ? "Ok" : "Nok");
  Serial.onReceive(Recvfunc);//on ESP32
  Serial.setTimeout(100);

  // Setup OneWire
  hub.attach(ds18b20);

  Serial.print("cpu speed = ");
  Serial.println(F_CPU);

  const int8_t temperature = 20;
  ds18b20.setTemperature(temperature);
}

int start = 0;
void loop() {
  // following function must be called periodically
  hub.poll();
  // this part is just for debugging (USE_SERIAL_DEBUG in OneWire.h must be enabled for output)
  if (hub.hasError()) hub.printError();

  if (millis() - start > 10000) {
    Serial.println("TimeOut Restart");
    reboot();
  }
}

int Recvfunc() {
  start = millis();
  if (Serial.available() > 0) {
    if (Serial.available() == 1||Serial.available() == 3) {
      String recv = Serial.readString();
      if (recv == "A")  // mlx temp amb
      {
        Serial.println(mlx.readAmbientTempC());
      } else if (recv == "B")  // mlx temp ir
      {
        Serial.println(mlx.readObjectTempC());
      } else if (recv == "C")  // bmp temp
      {
        bmp.performReading();
        Serial.println(bmp.temperature);
      } else if (recv == "D")  // bmp pressure
      {
        bmp.performReading();
        Serial.println(bmp.pressure);
      } else if (recv == "E")  // DS18B23 temp
      {
        GetTempDs();
      } else if (recv == "S25")  // Send TEMP 25
      {
            const int8_t temperature = 25;
            ds18b20.setTemperature(temperature);
      } else if (recv == "S50")  // Send TEMP 50
      {
            const int8_t temperature = 50;
            ds18b20.setTemperature(temperature);
      }else if (recv == "S20")  // Send TEMP 20
      {
            const int8_t temperature = 20;
            ds18b20.setTemperature(temperature);
      }else if (recv == "R")  // RESTART ESP
      {
        Serial.println("Restart");
        reboot();
      } else {
        Serial.println("USAGE");
        Serial.println("A = Get MLX90614 Ambiant");
        Serial.println("B = Get MLX90614 Ir");
        Serial.println("C = Get BMP388 Temp");
        Serial.println("D = Get BMP388 Pressure");
        Serial.println("E = Get DS18B20 Temp");
        Serial.println("R = RESTART");
        Serial.println("Other This Message");
      }
    } else {
      Serial.flush();
      Serial.println("USAGE");
      Serial.println("A = Get MLX90614 Ambiant");
      Serial.println("B = Get MLX90614 Ir");
      Serial.println("C = Get BMP388 Temp");
      Serial.println("D = Get BMP388 Pressure");
      Serial.println("E = Get DS18B20 Temp");
      Serial.println("R = RESTART");
      Serial.println("Other This Message");
    }
  }
  return 0;
}

void GetTempDs(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[9];
  byte addr[8];
  float celsius, fahrenheit;

  if (!oneWire.search(addr)) {
    Serial.println("NotFound");
    oneWire.reset_search();
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for (i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  }

  oneWire.reset();
  oneWire.select(addr);
  oneWire.write(0x44, 1);  // start conversion, with parasite power on at the end

  delay(1000);  // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = oneWire.reset();
  oneWire.select(addr);
  oneWire.write(0xBE);  // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for (i = 0; i < 9; i++) {  // we need 9 bytes
    data[i] = oneWire.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3;  // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;       // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3;  // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1;  // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
}
gegedvd commented 10 months ago

PlatformIO Project Configuration File

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:m5stack-atom]
platform = espressif32
board = m5stack-atom
framework = arduino
upload_protocol = esptool
upload_port = COM8
monitor_speed = 115200
lib_deps = 
    SPI
    Wire
    adafruit/Adafruit MLX90614 Library
    adafruit/Adafruit BMP3XX Library
    OneWire
    DallasTemperature
    orgua/OneWireHub@^3.0.0
gegedvd commented 10 months ago

I checked issue #102 VALUE_IPL and I didn't have 1ms on the debug pin , I adjusted the VALUE_IPL value from 51 to 71 to get 996µs and now the OneWireSlave works fine

@GeorgeIoak : can you explain different value of VALUE_IPL on ESP32 chip @240Mhz

Thanks a Lot

GeorgeIoak commented 10 months ago

Hi @gegedvd I'm not able to explain why we are getting different values to work. What I did to determine the value was in this post https://github.com/orgua/OneWireHub/issues/102#issuecomment-1500990889

What did you measure in order to find that you had to increase from 51 to 71? You mentioned that you didn't have 1ms but what value did you have? Maybe this value isn't always the same and my value was at 1 end of the range and now your value is at the other end of the acceptable range. I just ran a few tests adjusting VALUE_IPL until I was close to 1ms and the code was working but I didn't spend time trying to find the window of acceptable values.

gegedvd commented 10 months ago

Hello , thank you for our reply I have check with oscilloscope on debug pin with master 1w disconnect during measure IPL:51 => Debug:1.38ms not run IPL:55 => Debug:1.27ms not run IPL:61 => Debug:1.13ms run flirckly ... IPL:70 => Debug:1.01ms run (diff 10µs) IPL:71 => Debug:0.996ms run (diff 4µs better)

I run on Stack-M5 Atom-U USB-A STICK image

@GeorgeIoak do not hesitate to submit me a test on this platform