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:

[CODE lang="b4x" title="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[/CODE]

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

[CODE lang="b4x" title="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[/CODE]

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

[CODE lang="cpp" title="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
}[/CODE]

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:
How correctly init oneWire and sensors_ds18b20 after getting the pinNumber from B4R together with the pulling pin up?
 
Upvote 0
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
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.
Code:
OneWire* oneWire = new OneWire(o->toLong);
 DallasTemperature* sensors_ds18b20 = new DallasTemperature(oneWire);
 sensors_ds18b20->begin();
 
Upvote 0
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

Similar Threads

Back
Top