# Port Arduino sketch to particle

**URL:** <https://community.particle.io/t/port-arduino-sketch-to-particle/56653>\
**Category:** Firmware\
**Created:** [June 15, 2020, 6:30pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653 "2020-06-15T18:30:56Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 15, 2020, 6:30pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/1 "2020-06-15T18:30:56Z")

</div>

HI  
I have the following code running on an Arduino Uno but would really like it running on a Photon as I need to get the data output in to a database on a raspberry pi. I think the main issues are how the interupts work and the fact that the sketch is referencing some registers that will be specific to the Arduino.  
Thanks.

```auto

#include <Wire.h>

//Interface Definitions
int RxPin = 8; //The number of signal from the Rx

// Variables for Manchester Receiver Logic:
word sDelay = 280; //Small Delay about 1/4 of bit duration try like 250 to 500
word lDelay = 560; //Long Delay about 1/2 of bit duration try like 500 to 1000, 1/4 + 1/2 = 3/4
byte polarity = 1; //0 for lo->hi==1 or 1 for hi->lo==1 for Polarity, sets tempBit at start
byte tempBit = 1; //Reflects the required transition polarity
byte discards = 0; //how many leading "bits" need to be dumped, usually just a zero if anything eg discards=1
byte discNos = 0; //Counter for the Discards
boolean firstZero = false; //has it processed the first zero yet? This a "sync" bit.
boolean noErrors = true; //flags if signal does not follow Manchester conventions
//variables for Header detection
byte headerBits = 15; //The number of ones expected to make a valid header
byte headerHits = 0; //Counts the number of "1"s to determine a header
//Variables for Byte storage
byte dataByte = 0; //Accumulates the bit information
byte nosBits = 0; //Counts to 8 bits within a dataByte
byte maxBytes = 9; //Set the bytes collected after each header. NB if set too high, any end noise will cause an error
byte nosBytes = 0; //Counter stays within 0 -> maxBytes
//Bank array for packet (at least one will be needed)
byte manchester[12]; //Stores manchester pattern decoded on the fly
//Oregon bit pattern, causes nibble rotation to the right, ABCDabcd becomes DCBAdcba
byte oregon[] = {
  16, 32, 64, 128, 1, 2, 4, 8
};
byte csIndex = 0; //counter for nibbles needed for checksum
//Weather Variables
byte quadrant = 0; //used to look up 16 positions around the compass rose
double avWindspeed = 0.0;
double gustWindspeed = 0.0; //now used for general anemometer readings rather than avWindspeed
float rainTotal = 0.0;
float rainRate = 0.0;
double temperature = 0.0;
int humidity = 0;
double intTemp = 0;
double intHumi = 0;
double intPres = 0;
byte intSolar = 0; //eg Solar power
byte intLightning = 0; //eg Lightning Strikes
byte intUV = 0; //eg UV Light Levels
const char windDir[16][4] = {
  "N ", "NNE", "NE ", "ENE", "E ", "ESE", "SE ", "SSE", "S ", "SSW", "SW ", "WSW", "W ", "WNW", "NW ", "NNW"
};

byte scan = 0; // &7!=0 means that all three sensors has been detected, so it reports all three with meaningful figures first up (not the latest addition though)
byte seconds = 0; // Counter to trigger the 60 seconds worth of data.
byte batStat = 0; // bit1= temp, bit2=wind bit3=rain, bit4=exp if true then that sensor has not been logged for 20 minutes, its battery probably getting flat
byte logTemp = 0; // Counter for number of minutes a sensor reading is missed
byte logWind = 0; // Counter for number of minutes a sensor reading is missed
byte logRain = 0; // Counter for number of minutes a sensor reading is missed
byte logUV = 0; // Counter for number of minutes a sensor reading is missed
byte logExp = 0; // Counter for number of minutes a sensor reading is missed
int aday = 0; // Counts the number of minutes in a day and clears battery status every 24hrs

void setup() {
  Serial.begin(9600);
  pinMode(RxPin, INPUT);

  /*
  // Enable these if attempting to debug the program or the circuit
  Serial.println("Debug Manchester Version 18");
  Serial.print("Using a delay of 1/4 bitWaveform ");
  Serial.print(sDelay,DEC);
  Serial.print(" uSecs 1/2 bitWaveform ");
  Serial.print(lDelay,DEC);
  Serial.println(" uSecs ");
  if (polarity){
    Serial.println("Negative Polarity hi->lo=1");
  }
  else{
    Serial.println("Positive Polarity lo->hi=1");
  }
  Serial.print(headerBits,DEC);
  Serial.println(" bits expected for a valid header");
  if (discards){
    Serial.print(discards,DEC);
    Serial.println(" leading bits discarded from Packet");
  }
  else{
    Serial.println("All bits inside the Packet");
  }
  Serial.println("D 00 00001111 01 22223333 02 44445555 03 66667777 04 88889999 05 AAAABBBB 06 CCCCDDDD 07 EEEEFFFF 08 00001111 09 22223333 0A 44445555");
  */

  //Tutorial on using the BMP05 Press/Temp transducer https://www.sparkfun.com/tutorials/253

  // Initialize Timer1 for a 1 second interrupt
  // Thanks to http://www.engblaze.com/ for this section, see their Interrupt Tutorial
  cli(); // disable global interrupts
  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B
  // set compare match register to desired timer count:
  OCR1A = 15624;
  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);
  // enable timer compare interrupt:
  TIMSK1 |= (1 << OCIE1A);
  // enable global interrupts:
  sei();
}

//Routine Driven by Interrupt, trap 1 second interrupts, and output every minute
ISR(TIMER1_COMPA_vect) {
  seconds++;
  if (seconds == 60) { //make 60 for each output
    seconds = 0;
    //Serial.print("One second ...");
    //usbData();//comment this out to temporarily disable data every minute for debug
  }
} //end of interrupt routine

// Main routines, find header, then sync in with it, get a packet, and decode data in it, plus report any errors.
void loop() {
  tempBit = polarity ^ 1;
  noErrors = true;
  firstZero = false;
  headerHits = 0;
  nosBits = 0;
  maxBytes = 15; //too big for any known OS signal
  nosBytes = 0;
  discNos = discards;
  manchester[0] = 0;
  while (noErrors && (nosBytes < maxBytes)) {
    while (digitalRead(RxPin) != tempBit) {
    }
    delayMicroseconds(sDelay);
    if (digitalRead(RxPin) != tempBit) {
      noErrors = false;
    }
    else {
      byte bitState = tempBit ^ polarity;
      delayMicroseconds(lDelay);
      if (digitalRead(RxPin) == tempBit) {
        tempBit = tempBit ^ 1;
      }
      if (bitState == 1) {
        if (!firstZero) {
          headerHits++;
          if (headerHits == headerBits) {
          }
        }
        else {
          add(bitState);
        }
      }
      else {
        if (headerHits < headerBits) {
          noErrors = false;
        }
        else {
          if ((!firstZero) && (headerHits >= headerBits)) {
            firstZero = true;

          }
          add(bitState);
        }
      }
    }
  }

}

void add(byte bitData) {
  if (discNos > 0) {
    discNos--;//discard bits before real data
  }
  else {
    //the incoming bitstream has bytes placed in reversed nibble order on the fly, then the CS is done.
    if (bitData) {
      //if it is a '1' OR it in, others leave at a '0'
      manchester[nosBytes] |= oregon[nosBits];//places the reversed low nibble, with hi nibble, on the fly!!!
    }
    //Oregon Scientific sensors have specific packet lengths
    //Maximum bytes for each sensor must set once the sensor has been detected.

    if (manchester[0] == 0xA1) {
      maxBytes = 10; //wind
      csIndex = 18;
    }
    if (manchester[0] == 0xAF) {
      maxBytes = 9; //temp
      csIndex = 16;
    }
   
    nosBits++;
    //Pack the bits into 8bit bytes
    if (nosBits == 8) {
      nosBits = 0;
      nosBytes++;
      manchester[nosBytes] = 0; //next byte to 0 to accumulate data
    }
    //Check the bytes for a valid packet once maxBytes received
    if (nosBytes == maxBytes) {
      //hexBinDump();

      //Check Checksum first
      if (ValidCS(csIndex)) {
        //Process the byte array into Human readable numbers
        analyseData();
      }
      noErrors = false; //make it begin again from the start
    }
  }
}

//Useful to invoke to debug the byte Array
void hexBinDump() {
  //Serial.println("T A3 10100011 07 00000111 02 00000010 AA 10101010 F0 11110000 06 00000110 FF 11111111 07 00000111 33 00110011 60 01100000");
  Serial.print("D ");
  for ( int i = 0; i < maxBytes; i++) {
    byte mask = B10000000;
    if (manchester[i] < 16) {
      Serial.print("0");
    }
    Serial.print(manchester[i], HEX);
    Serial.print(" ");
    for (int k = 0; k < 8; k++) {
      if (manchester[i] & mask) {
        Serial.print("1");
      }
      else {
        Serial.print("0");
      }
      mask = mask >> 1;
    }
    Serial.print(" ");
  }
  Serial.println();
}

//Support Routines for Nybbles and CheckSum

// http://www.lostbyte.com/Arduino-OSV3/ (9) brian@lostbyte.com
// Directly lifted, then modified from Brian's work. Now nybble's bits are pre-processed into standard order, ie MSNybble + LSNybble
// CS = the sum of nybbles, 1 to (CSpos-1), then compared to CSpos nybble (LSNybble) and CSpos+1 nybble (MSNybble);
// This sums the nybbles in the packet and creates a 1 byte number, and this is compared to the two nybbles beginning at CSpos
// Note that Temp 9 bytes and anemometer 10 bytes, but rainfall uses 11 bytes per packet. (NB Rainfall CS spans a byte boundary)
bool ValidCS(int CSPos) {
  boolean ok = false;
  byte cs = 0;
  for (int x = 1; x < CSPos; x++) {
    byte test = nyb(x);
    cs += test;
  }
  //do it by nybbles as some CS's cross the byte boundaries eg rainfall
  byte check1 = nyb(CSPos);
  byte check2 = nyb(CSPos + 1);
  byte check = (check2 << 4) + check1;
  /*
  if (manchester[0]==0xA2){
  Serial.print(check1,HEX); //dump out the LSNybble Checksum
   Serial.print("(LSB), ");
   Serial.print(check2,HEX); //dump out the MSNybble Checksum
   Serial.print("(MSB), ");
   Serial.print(check,HEX); //dump out the Rx'ed predicted byte Checksum
   Serial.print("(combined), calculated = ");
   Serial.println(cs,HEX); //dump out the calculated byte Checksum
   //Serial.print(" "); //Space it out for the next printout
  }
  */
  if (cs == check) {
    ok = true;
  }
  return ok;
}
// Get a nybble from manchester bytes, short name so equations elsewhere are neater :-)
// Enables the byte array to be indexed as an array of nybbles
byte nyb(int nybble) {
  int bite = nybble / 2; //DIV 2, find the byte
  int nybb = nybble % 2; //MOD 2 0=MSB 1=LSB
  byte b = manchester[bite];
  if (nybb == 0) {
    b = (byte)((byte)(b) >> 4);
  }
  else {
    b = (byte)((byte)(b) & (byte)(0xf));
  }
  return b;
}

//enable debug dumps if formatted data required
void analyseData() {
  if (manchester[0] == 0xaf) { //detected the Thermometer and Hygrometer (every 53seconds)
    scan = scan | 1;
    logTemp = 0; //reset missing reads to zero
    thermom();
    dumpThermom();

  }
  if (manchester[0] == 0xa1) { //detected the Anemometer and Wind Direction (every 14seconds)
    scan = scan | 2;
    logWind = 0;//reset missing reads to zero
    anemom();
    dumpAnemom();
    
  }

  //Serial.println(scan,DEC);
  eraseManchester();
}

//Calculation Routines
/*The following bit has been identified by Xander Zimmerman as a 'battery low' indicator
  He used a variable voltage power supply to test signals from rainfall, temp/hum and anemometer eg
  - no more messages: < 2.1 V
  - switch to low < 2.6 V
  - only 1 Bit used: Byte 4; Bit 6: high => Bat low (Nyb8, Bit 2)
  This aligns with the nybble I suspected contained the Battery level indicator
  However it does not tally with my experiments. However I used resistors to lower the voltage to the sensor,
  rather than a precise and steady voltage. I am inclined to accept Xander's opinion here but reluctant
  to change my present strategy of notification if the sensor is not detected at all for 20 minutes.
  This strategy allows for instant collapse of the sensor whether it be low batteries, or the cold, or phyiscal damage
  or the transmitter suddenly being shielded or a lightning strike or any other quick demise. The Oregon LCD base console
  does not have icons that signal a low battery, or the absence of a signal. So if the "low battery" transmissions are
  missed then the sensor can drop out before action is taken.
  In the case of some batteries, I have them go "low" overnight when it has been very cold only to act normal again the next
  day as the air temperature rose. Some sort of flag system in the server code would need to capture and reain that status.
  However I am sure if you see value in using the "battery low" bit, then it will be easy enough to incorporate.
  Xander is also a fan of http://www.openhab.org/ for organising his home systems and also https://github.com/wfrog/wfrog
  for rendering the Oregon information into graphs etc.
*/

// WGR800 Wind speed sensor
// Sample Data:
// 0 1 2 3 4 5 6 7 8 9
// A1 98 40 8E 00 0C 70 04 00 34
// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3
// 10100001 10011000 01000000 10001110 00000000 00001100 01110000 00000100 00000000 00110100
// -------- -------- bbbb---- NRRRRRRR xxxx9999 xxxxxxxx CCCCDDDD xxxxFFFF 0000---- CCCCcccc
// Av Speed 0.4000000000m/s Gusts 0.7000000000m/s Direction: N

// byte(0)_byte(1) = Sensor ID?????
// bbbb = Battery indicator??? (7) My investigations would disagree here. After exhaustive low battery tests these bits did not change
// NRRRRRRR = Rolling Code Byte, the N bit is set to 1 for 64 cycles to indicate it is reset or new to the Rx box
// 9999 = Direction
// DDDD.CCCC = Gust Speed (m per sec)
// 0000.FFFF = Avg Speed(m per sec)
// multiply by 3600/1000 for km/hr
// ccccCCCC = 1 byte checksum cf. sum of nybbles
// packet length is 20 nybbles

void anemom() {
  //D A1 98 40 8E 08 0C 60 04 00 A4
  avWindspeed = ((nyb(16) * 10) + nyb(15)) * 2.23694/ 10;
  double gust = ((nyb(13) * 10) + nyb(12)) * 2.23694/ 10;
  // after every minute, reset gustWindspeed to avWindspeed and then take the highest gust after that (approx4 readings a minute)
  if (gust > gustWindspeed) {
    gustWindspeed = gust;
  }
  quadrant = nyb(9) & 0xF;
}
void dumpAnemom() {
  Serial.print("Av Speed ");
  Serial.print(avWindspeed);
  Serial.print(" mph, Gusts ");
  Serial.print(gustWindspeed);
  Serial.print(" mph, Direction: ");
  Serial.print(quadrant);
  Serial.print(" -> ");
  Serial.println(windDir[quadrant]);
}

// THGN800 Temperature and Humidity Sensor
// 0 1 2 3 4 5 6 7 8 9 Bytes
// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 nybbles
// 01011111 00010100 01000001 01000000 10001100 10000000 00001100 10100000 10110100 01111001 Bits
// -------- -------- bbbbcccc RRRRRRRR 88889999 AAAABBBB SSSSDDDD EEEE---- CCCCcccc -------- Explanation
// byte(0)_byte(1) = Sensor ID?????
// bbbb = Battery indicator??? (7), My investigations on the anemometer would disagree here. After exhaustive low battery tests these bits did not change
// RRRRRRRR = Rolling code byte
// nybble(5) is channel selector c (Switch on the sensor to allocate it a number)
// BBBBAAAA.99998888 Temperature in BCD
// SSSS sign for negative (- is !=0)
// EEEEDDDD Humidity in BCD
// ccccCCCC 1 byte checksum cf. sum of nybbles
// Packet length is 18 nybbles and indeterminate after that
// H 00 01 02 03 04 05 06 07 08 09 Byte Sequence
// D AF 82 41 CB 89 42 00 48 85 55 Real example
// Temperature 24.9799995422 degC Humidity 40.0000000000 % rel
void thermom() {
  temperature = (double)((nyb(11) * 100) + (nyb(10) * 10) + nyb(9)) / 10; //accuracy to 0.1 degree seems unlikely
  //The following line has been corrected by Darko in Italy, thank you, Grazie ragazzi!!!
  if (nyb(12) == 8) { // Trigger a negative temperature
    temperature = -1.0 * temperature;
  }
  humidity = (nyb(14) * 10) + nyb(13);
}
void dumpThermom() {
  Serial.print("Temperature ");
  Serial.print(temperature);
  Serial.print(" degC, Humidity ");
  Serial.print(humidity);
  Serial.println("% Rel");
}

// Formating routine for interface to host computer, output once a minute once all three sesnors have been detected
void usbData() {
  // Stn Id, Packet Type, Wind Quadrant, Wind Speed, Rain Tips, Ext temp, Int Temp, Int Pressure, Int Humidity
               //scan==15 means all 4 readings now have a valid value, ready for output on Serial
    //Battery/Signal status, OR in the the four status values for the signal connections.
    logTemp++;
    if (logTemp>40){
      batStat = batStat | 1;
      }
    logWind++;
    if (logWind>40){
      batStat = batStat | 2;
      }
    
    //reset the batStat to 0 every 24hours
    aday++;
    if (aday>1440){
      batStat=0;
      aday=0;
      }
    // Order: Battery Status, Quadrant, Wind Gust, Rainfall, Temperature, InternalTemp, Internal Pressure, Int Humidity, Solar Power, Lightning, UV Radiation
    Serial.print(batStat,DEC); //Send out the number to indicate if a sensor is not transmitting for maore than 20 mins. Low Battery or other damage.
    Serial.print(",");
    Serial.print(quadrant); //0-15 in 22.5 degrees steps clockwise
    Serial.print(",");
    Serial.print(gustWindspeed, 1); //Gust windspeed km/hr, not average windspeed (graphing over 10 samples gives Average)
    Serial.print(",");
    gustWindspeed = avWindspeed; //reset gust to average, then take the larger next reading
    Serial.print(",");
    Serial.print(temperature, 2); // OS Temperature Centigrade
    Serial.println();
  
}

void eraseManchester(){
  for( int i=0; i < 15; i++){
    manchester[i]=0;
  }
}

```

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 15, 2020, 7:00pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/2 "2020-06-15T19:00:15Z")

</div>

@bayesp, the hardware timer used in the code can be replaced by a [Software Timer](https://docs.particle.io/reference/device-os/firmware/photon/#software-timers) with the “interrupt” code remaining mostly the same. Software Timers are not as accurate as hardware timers but for your use case, a few milliseconds is tolerable IMO.

So, this chunk of code:

```auto
  // Initialize Timer1 for a 1 second interrupt
  // Thanks to http://www.engblaze.com/ for this section, see their Interrupt Tutorial
  cli(); // disable global interrupts
  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B
  // set compare match register to desired timer count:
  OCR1A = 15624;
  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);
  // enable timer compare interrupt:
  TIMSK1 |= (1 << OCIE1A);
  // enable global interrupts:
  sei();

```

would be replaced with a Timer declaration outside of `setup()` which could look like this:  
`Timer oneSecTimer(1000, oneSecCallback);` //Set interval to 1000ms or 1s

Then, in `setup()` you would start the time with:  
`oneSecTimer.start();`

And finally, the “interrupt” code, which is now the Software Timer callback code, becomes:

```auto
void oneSecCallback() {
  seconds++;
  if (seconds == 60) { //make 60 for each output
    seconds = 0;
  }
}

```

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 15, 2020, 7:14pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/3 "2020-06-15T19:14:57Z")

</div>

Wow, thanks for the speedy response. I’ll give it a go tomorrow.

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 16, 2020, 4:34pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/4 "2020-06-16T16:34:54Z")

</div>

Hi Sorry to be a pain. I tried to flash the modified code and the device goes offline almost instantly and I have to flash tinker over USB to get it back. I tried removing the timer as I am not using the function that relies on it but with the same result. It compiles fine, but flashing this firmware seems to kill it.  
I can flash the ‘blink and LED’ sketch OTA, so it definitely is an issue with my code.

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 16, 2020, 4:47pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/5 "2020-06-16T16:47:02Z")

</div>

@bayesp, can you share your code?

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 16, 2020, 5:12pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/6 "2020-06-16T17:12:37Z")

</div>

[https://go.particle.io/shared\_apps/5ee8f7608533f6000715cf90](https://go.particle.io/shared_apps/5ee8f7608533f6000715cf90)

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 16, 2020, 5:45pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/7 "2020-06-16T17:45:24Z")

</div>

@bayesp, you are running your code without `SYSTEM_THREAD(ENABLED)` and are not calling `Particle.process()` to keep give time to the DeviceOS to run. In loop(), you have `while()` statements which will block until bits are received, not allowing loop() to end and the DeviceOS getting time to run.

I suggest you run with `SYSTEM_THREAD(ENABLED)`, allowing the Software Timer thread to run better and preventing the application thread from blocking the DeviceOS. Keep in mind, though, that with threading enabled, the application thread will start immediately and not wait for the Particle Cloud connection so before you do any Cloud operations, you will want to make sure the connection is there. Typically this is done by checking `Paricle.connected()`.

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 16, 2020, 6:11pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/8 "2020-06-16T18:11:20Z")

</div>

Thanks again. I will try and implement your suggestions when I get a chance.

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 16, 2020, 7:15pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/9 "2020-06-16T19:15:24Z")

</div>

Thanks again, seems to be working now, at least I think it is but unusually there is no wind.

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 16, 2020, 7:58pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/10 "2020-06-16T19:58:33Z")

</div>

OK, mostly working but I am getting a panic, hard\_fault error frequently. My latest attempt is here:[https://go.particle.io/shared\_apps/5ee9195c8533f6001615d307](https://go.particle.io/shared_apps/5ee9195c8533f6001615d307)

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 17, 2020, 1:19pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/11 "2020-06-17T13:19:47Z")

</div>

So it worked all night, albeit erring and resetting regularly as mentioned above. I added a publish for the thermometer and that also worked, still with the recurring errors. I had to unplug it and plug it back in again and since then I only get temperature and humidity (although humidity is always 0, and no anemometer readings, but I am also not getting the errors?? so the rrors must be related to the anenom function? Its really tricky to debug as I didn’t write the original code and it was written for Arduino so some of it is maybe not quite right for a Photon. I dont really understand the point of a bitwise and with 0xF on a nibble as surely going to give you the same value back? Any ideas gratefully received.  
Latest version:  
[https://go.particle.io/shared\_apps/5ee9f3e56c2eea000c44526b](https://go.particle.io/shared_apps/5ee9f3e56c2eea000c44526b)

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 17, 2020, 1:44pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/12 "2020-06-17T13:44:58Z")

</div>

@bayesp, can you provide a link to the original library? Which hardware exactly is being used in this project (I assume it involves a 433MHz receiver)?

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 17, 2020, 2:46pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/13 "2020-06-17T14:46:54Z")

</div>

Sure.

> **[robwlakes/ArduinoWeatherOS](https://github.com/robwlakes/ArduinoWeatherOS)**
>
> Arduino Uno, 433MhzRx and OS WMR86 Weather Station - robwlakes/ArduinoWeatherOS

  
Yes, I am using a 433mhz receiver, like this.  

> **[WINGONEER RXB6 433Mhz Superheterodyne Wireless Receiver Module for...](https://www.amazon.co.uk/dp/B06XHJMC82/ref=cm_sw_r_cp_apa_i_wYI6EbWZ5HJXK)**
>
> Shop WINGONEER RXB6 433Mhz Superheterodyne Wireless Receiver Module for Arduino/ARM/AVR. Free delivery on eligible orders of £20 or more.

I only have the anenometer and temperature gauge.

Thanks

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 17, 2020, 7:39pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/14 "2020-06-17T19:39:08Z")

</div>

@bayesp, I get the impression that this library, which uses an interrupt-based Oregon data decoder is better suited to your application. The code includes a web server which you won’t need. The code would easily be adapted for the Photon.

> **[Arduino Intercepting Oregon Scientific Weather Station Data](https://buildthings.wordpress.com/arduino-intercepting-oregon-scientific-weather-station-anemometer-wind-vane-temperature-humidity-barometer-rain-gauge-data/)**
>
>   The Experiment: Arduino Intercepting Oregon Scientific 433Mhz Wireless Weather Station Data. Build a 433Mhz wireless weather station receiver around an Arduino UNO micro-controller, to recei…

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 17, 2020, 8:19pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/15 "2020-06-17T20:19:07Z")

</div>

Thanks. I had looked at this one but it is based on the OS protocol v2, my sensors use v3. I will see how hard it is to change the decoding from v2 to v3

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 17, 2020, 8:21pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/16 "2020-06-17T20:21:49Z")

</div>

@bayesp, if you look carefully, the V3 protocol is also supported.

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 17, 2020, 8:26pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/17 "2020-06-17T20:26:33Z")

</div>

Ah, sorry. Will take another look.

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 18, 2020, 1:44pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/18 "2020-06-18T13:44:44Z")

</div>

The saga continues.  
I took the code you suggested, removed most of what I don’t want, fixed the error that came up when first compiling and got a successful compile.  
[https://go.particle.io/shared\_apps/5eeb6615f6738c00074cbae5](https://go.particle.io/shared_apps/5eeb6615f6738c00074cbae5)  
I am now getting an SOS led signal followed by 14 flashes (heap error). Any ideas what I have done wrong this time?  
Thanks

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [June 18, 2020, 3:33pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/19 "2020-06-18T15:33:52Z")

</div>

@bayesp, calling `Particle.publish()` in an interrupt service routine is an absolute no-no! That’s where your heap error is coming from. At best, blink a LED an an indicator. You can’t even put a `Serial.print()!

```auto
void ext_int_1(void) {
    Particle.publish("interupt", "found", PRIVATE); <---- CAN'T DO THIS IN ISR!!!
  static word last;
  // determine the pulse length in microseconds, for either polarity
  pulse = micros() - last;
  last += pulse;
}

```

---

<div class="post-metadata">

**Author:** ![bayesp](https://avatars.discourse-cdn.com/v4/letter/b/eb8c5e/32.png) [@bayesp](https://community.particle.io/u/bayesp)\
**Post date:** [June 18, 2020, 3:46pm UTC](https://community.particle.io/t/port-arduino-sketch-to-particle/56653/20 "2020-06-18T15:46:19Z")

</div>

Oops. I just wanted to see if it even was seeing a pulse as I was getting no output at all. Will try again.

[Next page](https://community.particle.io/t/port-arduino-sketch-to-particle/56653.md?page=2)
