C/C++ Question [Solved] NewPing Wrapper

Johan Schoeman

Expert
Licensed User
Longtime User
I am trying to wrap the NewPing library (juts initialize and method ping_cm for now).

This is my rNewPing.f file:
B4X:
#pragma once
#include "B4RDefines.h"
//~dependson: <NewPing.h>

namespace B4R {
//    ~Version: 1.00
//    ~ShortName: NewPing
    class B4RNewPing {
        private:
            uint8_t backend[sizeof(NewPing)];
        public:
            //~hide
            NewPing* np;
            /**
            *Initializes the object.
            */
            void Initialize(Byte triggerpin, Byte echopin, UInt maxcmdistance);
        
            ULong ping_cm(UInt maxcmdistance);
    };
}

This is my rNewPing.cpp file:
B4X:
#include "B4RDefines.h"
namespace B4R {
    void B4RNewPing::Initialize(Byte triggerpin, Byte echopin, UInt maxcmdistance) {
            np =  new (backend) NewPing(triggerpin, echopin, maxcmdistance);
    }
    
    ULong B4RNewPing::ping_cm(UInt maxcmdistance) {   
        return np->ping_cm(maxcmdistance);
    }
    
}

This is my rNewPing.xml file:
B4X:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
    <doclet-version-NOT-library-version>1.00</doclet-version-NOT-library-version>
    <class>
        <name>B4R::B4RNewPing</name>
        <shortname>NewPing</shortname>

        
        <method>
            <name DesignerName="Initialize">Initialize</name>
            <comment>Initializes the object
TrigPin - Trigger Pin
EchoPin - Echo Pin
maxcmdistance - Maximum Distance in cm
Example:&lt;code&gt;
np.Initialize(TrigPin, EchoPin, maxcmdistance)&lt;/code&gt;</comment>
            <returntype>B4R::void</returntype>
            <parameter>
                <name>TrigPin</name>
                <type>Byte</type>
            </parameter>
            <parameter>
                <name>EchoPin</name>
                <type>Byte</type>
            </parameter>
            <parameter>
                <name>maxcmdistance</name>
                <type>UInt</type>
            </parameter>
        </method>
        <method>
            <name DesignerName="ping_cm">ping_cm</name>
            <comment>Return the ping distance in cm (max = maxcmdistance)</comment>
            <returntype>B4R::ULong</returntype>
            <parameter>
                <name>maxcmdistance</name>
                <type>UInt</type>
            </parameter>
        </method>
    </class>
    <version>1</version>
    <dependsOn>&lt;NewPing.h&gt;</dependsOn>
</root>

The constructor in NewPing.cpp is as follows:

B4X:
NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance) {
//    ::Serial.println("aaa");
#if DO_BITWISE == true
    _triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin.
    _echoBit = digitalPinToBitMask(echo_pin);       // Get the port register bitmask for the echo pin.

    _triggerOutput = portOutputRegister(digitalPinToPort(trigger_pin)); // Get the output port register for the trigger pin.
    _echoInput = portInputRegister(digitalPinToPort(echo_pin));         // Get the input port register for the echo pin.

    _triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin.
#else
    _triggerPin = trigger_pin;
    _echoPin = echo_pin;
#endif

    set_max_distance(max_cm_distance); // Call function to set the max sensor distance.

#if (defined (__arm__) && (defined (TEENSYDUINO) || defined(PARTICLE))) || DO_BITWISE != true
    pinMode(echo_pin, INPUT);     // Set echo pin to input (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode).
    pinMode(trigger_pin, OUTPUT); // Set trigger pin to output (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode).
#endif

#if defined (ARDUINO_AVR_YUN)
    pinMode(echo_pin, INPUT);     // Set echo pin to input for the Arduino Yun, not sure why it doesn't default this way.
#endif

#if ONE_PIN_ENABLED != true && DO_BITWISE == true
    *_triggerMode |= _triggerBit; // Set trigger pin to output.
#endif
}

The method that I am calling in NewPing.cpp is as follows:
B4X:
unsigned long NewPing::ping_cm(unsigned int max_cm_distance) {
    unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS.
//    ::Serial.println("bbb");
#if ROUNDING_ENABLED == false
//    ::Serial.println(echoTime / US_ROUNDTRIP_CM);
    return (echoTime / US_ROUNDTRIP_CM);              // Call the ping method and returns the distance in centimeters (no rounding).
#else
    return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
#endif
}

I can see the wrapper in the B4R IDE (rNewPing version 1.00) and from the B4R project the library is initialized correctly (check it by adding ::Serial.println("xxx"). But I get a cast error when trying to return the "distance" from the the library method to B4R. My B4R code is as follows:
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    
    Dim t As Timer
    
    Dim dst As UInt = 500
    Dim nbr As ULong
    Dim pin9 As Byte = 9
    Dim pin10 As Byte = 10
    
    Dim np As NewPing
    
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    t.Initialize("t_tick", 1000)
    np.Initialize(pin9, pin10, dst)
    nbr = 0
    t.Enabled = True

End Sub

Sub t_tick
    
    np.ping_cm(dst)
    nbr = np.ping_cm(dst)                 'THIS GIVE A CAST ERROR
    
    
End Sub

Error in the IDE is as follows:

upload_2019-6-1_7-24-23.png



From what I can see it that the constructor expects a Byte, Byte, UInt and the method expects a UInt and should return a ULong.

Using ::Serial.println(echoTime / US_ROUNDTRIP_CM); inside the library prints/logs the correct value is the B4R log.

I have edited all the above (.h, .cpp, .xml) in Notepad++ so maybe I have an error in the .xml?

Will appreciate some advise to get the cast type error sored out.

Thanks

Johan
 

Attachments

  • upload_2019-6-1_7-22-3.png
    upload_2019-6-1_7-22-3.png
    57.1 KB · Views: 459
Top