B4R Question initialization inside Inline-C from B4R

peacemaker

Expert
Licensed User
Longtime User
Hi, All

I'm trying to make .bas modules for each hardware sensor in such style:

This code works only if the sensor data pin is pulled up by a resistor:
'Module name = "esp_ds18b20"
'Libs: https://github.com/PaulStoffregen/OneWire; https://github.com/milesburton/Arduino-Temperature-Control-Library
'1wire port is defined below in Inline-C code

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public temperature_ds18b20 As Float    'centigrees
    Private Timer1 As Timer
    Dim Ready_flag As Boolean
End Sub

Sub Start_ds18b20
    Log("Start reading ds18b20...")
    RunNative("setup_ds18b20", Null)
    Timer1.Initialize("Timer1_Tick", 2000)
    Timer1.Enabled = True
End Sub

Sub Stop
    Timer1.Enabled = False
    Log("ds18b20 stopped")
End Sub

Private Sub Timer1_Tick
    RunNative("read_ds18b20",Null)
    Log("ds18b20 temp=", others.Numb2(temperature_ds18b20))
    Ready_flag = True
End Sub

#if C
// Include the libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// DS18B20 temperature sensor data wire is plugged into pin 17
#define ONE_WIRE_BUS 17

// Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to Dallas Temperature.
    DallasTemperature sensors_ds18b20(&oneWire);

void setup_ds18b20 (B4R::Object* unused) {
  // Start up the library.
  sensors_ds18b20.begin();
  sensors_ds18b20.setResolution(12); //ADC resulution 9...12
}

void read_ds18b20 (B4R::Object* unused) {
//    Request temperature readings from ALL devices on the bus
    sensors_ds18b20.requestTemperatures();
    delay(20);
//    You can have more than one DS18B20 on the same bus. 0 refers to the first IC on the wire. sensors_ds18b20.getTempCByIndex(0) = °C, sensors_ds18b20.getTempFByIndex(0) = °F
     b4r_esp_ds18b20::_temperature_ds18b20 = sensors_ds18b20.getTempCByIndex(0);
}
#End if

But the sensor is able to work with internal pulling up:

This works without extra resistor:
'Module name = "esp_ds18b20"
'Libs: https://github.com/PaulStoffregen/OneWire; https://github.com/milesburton/Arduino-Temperature-Control-Library
'1wire port is defined below in Inline-C code

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Private pin1wire As Pin
    Dim pinNumber As Int = 17
    Public temperature_ds18b20 As Float    'centigrees
    Private Timer1 As Timer
    Dim Ready_flag As Boolean
End Sub

Sub Start_ds18b20
    Log("Start reading ds18b20...")
    pin1wire.Initialize(pinNumber, pin1wire.MODE_INPUT_PULLUP)    'it helps ! But how to pass "pinNumber" to Inline-C correctly ?
    RunNative("setup_ds18b20", Null)
    Timer1.Initialize("Timer1_Tick", 2000)
    Timer1.Enabled = True
End Sub

Sub Stop
    Timer1.Enabled = False
    Log("ds18b20 stopped")
End Sub

Private Sub Timer1_Tick
    RunNative("read_ds18b20",Null)
    Log("ds18b20 temp=", others.Numb2(temperature_ds18b20))
    Ready_flag = True
End Sub

#if C
// Include the libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// DS18B20 temperature sensor data wire is plugged into pin 17
#define ONE_WIRE_BUS 17  // SECOND DECLARATION :(((

// Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to Dallas Temperature.
    DallasTemperature sensors_ds18b20(&oneWire);

void setup_ds18b20 (B4R::Object* unused) {
  // Start up the library.
  sensors_ds18b20.begin();
  sensors_ds18b20.setResolution(12); //ADC resulution 9...12
}

void read_ds18b20 (B4R::Object* unused) {
//    Request temperature readings from ALL devices on the bus
    sensors_ds18b20.requestTemperatures();
    delay(20);
//    You can have more than one DS18B20 on the same bus. 0 refers to the first IC on the wire. sensors_ds18b20.getTempCByIndex(0) = °C, sensors_ds18b20.getTempFByIndex(0) = °F
     b4r_esp_ds18b20::_temperature_ds18b20 = sensors_ds18b20.getTempCByIndex(0);
}
#End if

Normal situation if the pinNumber of B4R is passed also into Inline-C, but how correctly to init the objects with this portNumber ?

This does not help:
void setup_ds18b20 (B4R::Object* unused) {
  // Start up the library.
  pinMode(ONE_WIRE_BUS, INPUT_PULLUP);   //does not help, but in B4R it helped there
  sensors_ds18b20.begin();
  sensors_ds18b20.setResolution(12); //ADC resulution 9...12
}

Next code does not read correctly, no pulling up applied:
B4X:
'Module name = "esp_ds18b20"
'Libs: https://github.com/PaulStoffregen/OneWire; https://github.com/milesburton/Arduino-Temperature-Control-Library
'1wire port is defined below in Inline-C code

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Private pin1wire As Pin
    Dim pinNumber As Int = 17
    Public temperature_ds18b20 As Float    'centigrees
    Private Timer1 As Timer
    Dim Ready_flag As Boolean
End Sub

Sub Start_ds18b20
    Log("Start reading ds18b20...")
    pin1wire.Initialize(pinNumber, pin1wire.MODE_INPUT_PULLUP)    'it helps ! But how to pass "pinNumber" to Inline-C correctly ?
    RunNative("setup_ds18b20", pinNumber)
    Timer1.Initialize("Timer1_Tick", 2000)
    Timer1.Enabled = True
End Sub

Sub Stop
    Timer1.Enabled = False
    Log("ds18b20 stopped")
End Sub

Private Sub Timer1_Tick
    RunNative("read_ds18b20",Null)
    Log("ds18b20 temp=", others.Numb2(temperature_ds18b20))
    Ready_flag = True
End Sub

#if C
// Include the libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire;

// Pass oneWire reference to Dallas Temperature.
    DallasTemperature sensors_ds18b20(&oneWire);

void setup_ds18b20 (B4R::Object* o) {
  // Start up the library.
  OneWire oneWire(o->toLong());
   DallasTemperature sensors_ds18b20(&oneWire);
 
  sensors_ds18b20.begin();
  sensors_ds18b20.setResolution(12); //ADC resulution 9...12
}

void read_ds18b20 (B4R::Object* unused) {
//    Request temperature readings from ALL devices on the bus
    sensors_ds18b20.requestTemperatures();
    delay(20);
//    You can have more than one DS18B20 on the same bus. 0 refers to the first IC on the wire. sensors_ds18b20.getTempCByIndex(0) = °C, sensors_ds18b20.getTempFByIndex(0) = °F
     b4r_esp_ds18b20::_temperature_ds18b20 = sensors_ds18b20.getTempCByIndex(0);
}
#End if

How correctly to declare the pinNumber only once in B4R, pass it into Inline-C code for initialization without second declaration of this pinNumber there again?
 
Last edited:

peacemaker

Expert
Licensed User
Longtime User
How correctly init oneWire and sensors_ds18b20 after getting the pinNumber from B4R together with the pulling pin up?
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
OK, thanks Erel,

Is this incorrect way ?

B4X:
void setup_ds18b20 (B4R::Object* o) {
  // Start up the library.
  OneWire oneWire(o->toLong());
   DallasTemperature sensors_ds18b20(&oneWire);
 
  sensors_ds18b20.begin();
  sensors_ds18b20.setResolution(12); //ADC resulution 9...12
}

How correctly ?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I think that I understand the problem. The local variables are declared on the stack, so they are released once the method ends.

You need to create them with new. This way they will be allocated on the heap.
Experts note: B4R doesn't use the regular "new" and instead use the variant that allows setting the memory location. This is required for a more sophisticated memory management, but not important in this case.
B4X:
OneWire* oneWire = new OneWire(o->toLong);
 DallasTemperature* sensors_ds18b20 = new DallasTemperature(oneWire);
 sensors_ds18b20->begin();
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
Seems, did not help. It compiles, but read wrong, like the pulling up is not applied
B4X:
'Module name = "esp_ds18b20"
'Libs: https://github.com/PaulStoffregen/OneWire; https://github.com/milesburton/Arduino-Temperature-Control-Library
'1wire port is defined below in Inline-C code

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Private pin1wire As Pin
    Dim pinNumber As Int = 17
    Public temperature_ds18b20 As Float    'centigrees
    Private Timer1 As Timer
    Dim Ready_flag As Boolean
End Sub

Sub Start_ds18b20
    Log("Start reading ds18b20...")
    pin1wire.Initialize(pinNumber, pin1wire.MODE_INPUT_PULLUP)
    RunNative("setup_ds18b20", pinNumber)
    Timer1.Initialize("Timer1_Tick", 2000)
    Timer1.Enabled = True
End Sub

Sub Stop
    Timer1.Enabled = False
    Log("ds18b20 stopped")
End Sub

Private Sub Timer1_Tick
    RunNative("read_ds18b20",Null)
    Log("ds18b20 temp=", others.Numb2(temperature_ds18b20))
    Ready_flag = True
End Sub

#if C
// Include the libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire;

// Pass oneWire reference to Dallas Temperature.
    DallasTemperature sensors_ds18b20(&oneWire);

void setup_ds18b20 (B4R::Object* o) {
  // Start up the library.
    OneWire* oneWire = new OneWire(o->toLong());
    DallasTemperature* sensors_ds18b20 = new DallasTemperature(oneWire);
   
    sensors_ds18b20->begin();
    sensors_ds18b20->setResolution(12); //ADC resulution 9...12
}

void read_ds18b20 (B4R::Object* unused) {
//    Request temperature readings from ALL devices on the bus
    sensors_ds18b20.requestTemperatures();
    delay(20);
//    You can have more than one DS18B20 on the same bus. 0 refers to the first IC on the wire. sensors_ds18b20.getTempCByIndex(0) = °C, sensors_ds18b20.getTempFByIndex(0) = °F
     b4r_esp_ds18b20::_temperature_ds18b20 = sensors_ds18b20.getTempCByIndex(0);
}
#End if

Strange, but works only such:
B4X:
#if C
// Include the libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// DS18B20 temperature sensor data wire is plugged into pin 17
#define ONE_WIRE_BUS 17  // SECOND DECLARATION :(((

// Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(ONE_WIRE_BUS);

// Pass oneWire reference to Dallas Temperature.
    DallasTemperature sensors_ds18b20(&oneWire);

void setup_ds18b20 (B4R::Object* unused) {
  // Start up the library.
  sensors_ds18b20.begin();
  sensors_ds18b20.setResolution(12); //ADC resulution 9...12
}

void read_ds18b20 (B4R::Object* unused) {
//    Request temperature readings from ALL devices on the bus
    sensors_ds18b20.requestTemperatures();
    delay(20);
//    You can have more than one DS18B20 on the same bus. 0 refers to the first IC on the wire. sensors_ds18b20.getTempCByIndex(0) = °C, sensors_ds18b20.getTempFByIndex(0) = °F
     b4r_esp_ds18b20::_temperature_ds18b20 = sensors_ds18b20.getTempCByIndex(0);
}
#End if
 
Last edited:
Upvote 0
Top