arduino code conversion

Benjie

Senior Member
Hi there,
I went across a nice variometer project designed around Arduino Nano which, of course, has a Arduino code totally unknown by me.
Is there anyone who can offer an initial translation of that code to Pickaxe code for a 08M?
The Arduino code is attached.

Many thanks to this community.

Benjie
Code:
// All code by Rolf R Bakke, Oct 2012


#include <Wire.h>

const byte led = 13;

unsigned int calibrationData[7];
unsigned long time = 0;

float toneFreq, toneFreqLowpass, pressure, lowpassFast, lowpassSlow ;

int ddsAcc;


void setup()
{
  Wire.begin();
  Serial.begin(115200);
  setupSensor();
  
  pressure = getPressure();
  lowpassFast = lowpassSlow = pressure;
}


void loop()
{
  pressure = getPressure();
  
  lowpassFast = lowpassFast + (pressure - lowpassFast) * 0.1;
  lowpassSlow = lowpassSlow + (pressure - lowpassSlow) * 0.05;
  
  toneFreq = (lowpassSlow - lowpassFast) * 50;
  
  toneFreqLowpass = toneFreqLowpass + (toneFreq - toneFreqLowpass) * 0.1;
   
  toneFreq = constrain(toneFreqLowpass, -500, 500);
  
  ddsAcc += toneFreq * 100 + 2000;
  
  if (toneFreq < 0 || ddsAcc > 0) 
  {
    tone(2, toneFreq + 510);  
  }
  else
  {
    noTone(2);
  }
  
  ledOff(); 
  while (millis() < time);        //loop frequency timer
  time += 20;
  ledOn();
}


long getPressure()
{
  long D1, D2, dT, P;
  float TEMP;
  int64_t OFF, SENS;
 
  D1 = getData(0x48, 10);
  D2 = getData(0x50, 1);

  dT = D2 - ((long)calibrationData[5] << 8);
  TEMP = (2000 + (((int64_t)dT * (int64_t)calibrationData[6]) >> 23)) / (float)100;
  OFF = ((unsigned long)calibrationData[2] << 16) + (((int64_t)calibrationData[4] * dT) >> 7);
  SENS = ((unsigned long)calibrationData[1] << 15) + (((int64_t)calibrationData[3] * dT) >> 8);
  P = (((D1 * SENS) >> 21) - OFF) >> 15;
  
  //Serial.println(TEMP);
  //Serial.println(P);
  
  return P;
}


long getData(byte command, byte del)
{
  long result = 0;
  twiSendCommand(0x77, command);
  delay(del);
  twiSendCommand(0x77, 0x00);
  Wire.requestFrom(0x77, 3);
  if(Wire.available()!=3) Serial.println("Error: raw data not available");
  for (int i = 0; i <= 2; i++)
  {
    result = (result<<8) | Wire.read(); 
  }
  return result;
}


void setupSensor()
{
  twiSendCommand(0x77, 0x1e);
  delay(100);
  
  for (byte i = 1; i <=6; i++)
  {
    unsigned int low, high;

    twiSendCommand(0x77, 0xa0 + i * 2);
    Wire.requestFrom(0x77, 2);
    if(Wire.available()!=2) Serial.println("Error: calibration data not available");
    high = Wire.read();
    low = Wire.read();
    calibrationData[i] = high<<8 | low;
    Serial.print("calibration data #");
    Serial.print(i);
    Serial.print(" = ");
    Serial.println( calibrationData[i] ); 
  }
}


void twiSendCommand(byte address, byte command)
{
  Wire.beginTransmission(address);
  if (!Wire.write(command)) Serial.println("Error: write()");
  if (Wire.endTransmission()) 
  {
    Serial.print("Error when sending command: ");
    Serial.println(command, HEX);
  }
}


void ledOn()
{
  digitalWrite(led,1);
}


void ledOff()
{
  digitalWrite(led,0);
}
 
Last edited by a moderator:

hippy

Technical Support
Staff member
Most of the code can be converted to PICAXE Basic but the difficult part would be converting the maths which uses 64-bit signed integers and floating point, neither of which the PICAXE natively supports.

In cases like that the best approach is not to attempt a one-for-one code conversion but to determine what the program is doing and then figure out how the same results can be achieved with what the PICAXE supports.

It may often be that existing code is how it is because that is what is supported. It doesn't always mean it's the best way to do it or that there aren't other alternatives. A PICAXE solution can often involve stepping back from how someone else is doing it and coming back in from the direction of what it is attempting to achieve.

If you have a link to the project you are trying to convert, details or part number of the pressure sensor used, details of how the product operates, that may help in providing an alternative solution.
 

Benjie

Senior Member
Thank you hippy for the usual fast response. The full project based on Arduino can be seen on https://www.rcgroups.com/forums/showthread.php?1749208-DIY-simple-and-inexpensive-Arduino-based-sailplane-variometer&query=DIY simple inexpensive "Arduino-based" sailplane variometer.

I did several projects in the past with Picaxe but I lost the code familiarity. That's why I call for help.
Basically the code converts a I2C output from a pressure sensor module into a serial data to be transmitted. In between it converts the sensor data into a two tones pulsed with a frequency proportional to the pressure variation. I am sure that something similar has been developed among the forum members but I didn't find it yet. Can you help further?
Thanks,
 

hippy

Technical Support
Staff member
A forum search on "variometer" seems to turn up a few threads though I'm not sure all are relevant.

As I understand it a variometer determines rate of climb or descent and in this case adjusts the frequency of an output tone depending on how fast it's climbing or descending.

It may be possible to determine that simply from relative pressure readings which might simplify calculations.

I would do it in two parts; determine rate of climb and descent, then decide the frequency of tone from that.
 

premelec

Senior Member
I expect you are using this for sailplane [glider] instrument... shouldn't be too hard to take readings and compare if pressure going up or down and then you can get fancy with adjustable sensitivity and audio pitch variation and modulation. An interesting project and as Hippy suggests you can likely generate and understand your own code better than understanding someone else's... ;-0
 

eggdweather

Senior Member
You can buy the excellent Bosch BMP180 pressure sensor like this: http://www.ebay.co.uk/itm/BMP280-Module-Digital-Barometric-Pressure-Sensor-for-Arduino-BMP180-replacement-/162071253273 for £2.50 and it has the I2C or SPI bus connections, enabling the Picaxe to read pressure and it can easily detect pressure/altitude changes of 100cm, I use one in my model aircraft as a variometer albelit withe code written in C similar to your example. Getting pressure and then determining rate of change does not need floating point as all you need is the difference. There is code on this forum to read it, that's the hardest task and I think rate of change is simpler which can then be mapped to a picaxe sound command to give you the varying pitch with altitude changes.
 

Benjie

Senior Member
You can buy the excellent Bosch BMP180 pressure sensor like this: http://www.ebay.co.uk/itm/BMP280-Module-Digital-Barometric-Pressure-Sensor-for-Arduino-BMP180-replacement-/162071253273 for £2.50 and it has the I2C or SPI bus connections, enabling the Picaxe to read pressure and it can easily detect pressure/altitude changes of 100cm, I use one in my model aircraft as a variometer albelit withe code written in C similar to your example. Getting pressure and then determining rate of change does not need floating point as all you need is the difference. There is code on this forum to read it, that's the hardest task and I think rate of change is simpler which can then be mapped to a picaxe sound command to give you the varying pitch with altitude changes.
In fact I'm considering to design my own code using the new part 08M2 and a GY-63 MS5611 module which include the voltage regulator. What I need to detect is only the pressure variation storing the value at two intervals and process the difference.
Is there any example in the forum showing the code for correct extraction of the binary pressure data using the i2c slave inputs?
I never used that before.

thanks to you all.
 
Last edited:

eggdweather

Senior Member
I had a look at the data sheet, it's a 3.3v device but most break-out boards include a voltage regulator. It's a complicated device to use, almost identical to the Bosch in that regard, you have to read the individual device calibration values, then the reading of temperature as coefficients then calculate pressure, the final result is a 24-bit 3-byte result. There must be a simpler device on the market, I think both of the devices being considered are very wide range hence the large number results for wide dynamic range. There are analogue sensors around that would require the use of the ADC port and most probably 1024 / 10-bit resolution is more than adequate for a variometer, even if it were 1024 metres total measuring range, but for a variometer the current pressure would be normalised to zero, then rate of pressure change from there converted to sound/frequency variations.

I was thinking about the Freescale MPX sensors that are available in either gauge or differential variants.

The MPX4115 is closest to the Bosch BMP180 and has a 0.8-4.8 voltage output for normal ranges of air pressure, that would suit a variometer providing your not planning very high altitudes.
 
Last edited:
Top