P2 module Hanging problem on P1 to P2 migration

I have project which is working on P1 module.
then after i move on it to P2 module using P1 to P2 migration process, but it Couse problem
same code which work perfectly on P1 is not work on P2 also P2 module start hanging issue.
I use these library for my code,

#include "Discharger.h"
#include "Bluetooth.h"
#include "LcdScreen.h"
#include <LiquidCrystal.h>
#include <I2CButton.h>
#include "thermistor.h"
#include "MCP23017-RK.h"
#include "Countimer.h"
#include "RunningAverage.h"
#include "SerialBufferRK.h"
#include "PID_v1.h"
#include "PID_AutoTune_v0.h"
#include "Adafruit_MCP3008.h"  

is there any chance that problem occur from any one of these library.

please help me out of these problem,
thank you:)

It really could be anything. You need to remove functionality from your app to isolate what library is not working properly.

How do I get P2 Dev kit?

The P2 evaluation board is not generally available. If you are an enterprise customer you can ask your sales account executive, but otherwise it will be difficult to get one.

The Photon 2, which has a P2 on it, will be the official P2 development kit, but it won’t be available until 2023.

I check it out my code and i found that “SerialBufferRK” library could be problem

after i use code line Serial1.begin(38400, SERIAL_FLOW_CONTROL_NONE);
device is hang

I ran this program and was able to initialize Serial1 on the P2 on 5.1.0 without difficulties:

#include "Particle.h"

SerialLogHandler logHandler;

void setup() {
    waitFor(Serial.isConnected, 15000);
    delay(1000);

    Log.info("before Serial1.begin");
    Serial1.begin(38400, SERIAL_FLOW_CONTROL_NONE);
    Log.info("after Serial1.begin");
}

void loop() {
    while(Serial1.available()) {
        int c = Serial1.read();
        Serial.write(c);
    }
}

Output:

0000001314 [net.lwip_rltk] INFO: get_eap_phase
0000002300 [app] INFO: before Serial1.begin
0000002302 [app] INFO: after Serial1.begin
0000006004 [net.lwip_rltk] INFO: get_eap_phase
0000006249 [net.lwip_rltk] INFO: get_eap_phase
0000006297 [net.ifapi] INFO: Netif wl3 link UP
0000006299 [system.nm] INFO: State changed: IFACE_UP -> IFACE_LINK_UP
1 Like

I ran this program for Serial communication in that i use #include “SerialBufferRK.h” library for communication.
and i made buffer for Serial1 which is already i used in P1 board.
so this code runs 2-3 seconds and after that device hangs.

#include “Particle.h”
#include “SerialBufferRK.h”

SerialBuffer<4096> serBuf(Serial1);
SerialLogHandler logHandler;

SYSTEM_THREAD(ENABLED);

void setup() {
waitFor(Serial.isConnected, 15000);
delay(1000);
Log.info(“before Serial1.begin”);
Serial1.begin(38400, SERIAL_FLOW_CONTROL_NONE);
Log.info(“after Serial1.begin”);
}

void loop() {
if(serBuf.available()) {
int c = serBuf.read();
Serial.write(c);
}
if (Serial.available())
{
int a = Serial.read();
serBuf.write(a);
}
}

  • Upgrade to version 0.0.3 of SerialBufferRK
  • Add a call to serBuf.setup() to setup()

The stack size for the serial buffer thread was too small for the P2, or maybe Device OS 5.0.x. I increased it to 512 bytes in version 0.0.3.

I used this code, which also prints serial debugging log messages. I also connected a USB serial adapter to RX/TX and data transmission at 38400 is working properly in both directions.

#include "Particle.h"
#include "SerialBufferRK.h"

SerialBuffer<4096> serBuf(Serial1);
SerialLogHandler logHandler;

SYSTEM_THREAD(ENABLED);

void setup()
{
    waitFor(Serial.isConnected, 15000);
    delay(1000);
    Log.info("before Serial1.begin");
    Serial1.begin(38400, SERIAL_FLOW_CONTROL_NONE);
    Log.info("after Serial1.begin");

    serBuf.setup();
}

void loop()
{
    if (serBuf.available())
    {
        int c = serBuf.read();
        Serial.write(c);
    }
    if (Serial.available())
    {
        int a = Serial.read();
        serBuf.write(a);
    }
    static unsigned long loopCheck = 0;
    if (millis() - loopCheck > 5000) {
        loopCheck = millis();
        Log.info("loop running");
    }
}

Thank you for help. It work great.

But now getting another issue related to timer ISR. Currently I am using 1ms timer and due to that if more task is declared in ISR or outside ISR(by checking one flag) then also code routing is not working properly.

In attached code, On LCD I am not getting fully character due to 1mS timer. If I changed it to 10/100 ms then it works great. So is there any issue related to library or P2 has some limitation for inbuilt timer subroutine?

#include "particle.h"
#include <LiquidCrystal.h>
#include "SerialBufferRK.h"
#include "thermistor.h"
#include "Adafruit_MCP3008.h"
#include "MCP23017-RK.h"
#include <I2CButton.h>


SYSTEM_THREAD(ENABLED);

THERMISTOR gxThermistorTh1(A1, 10000, 3950, 10000, 1);
THERMISTOR gxThermistorTh2(3, 10000, 3950, 10000, 2);
SerialBuffer<4096> serBuf(Serial1);
LiquidCrystal lcd(D10, D5, S5, S4, S3, S2);
Adafruit_MCP3008 gxAdcChip;

////////////////////////////////////////////////////////////////////////////////
Timer timer(1, vIsrForTimer);  
//////////////////////////////////////////////////////////////////

uint8_t cnt;
float fBatActualVolt, fModuleTestBatActualVolt;

// 
void setup() {
  Serial1.begin(38400, SERIAL_FLOW_CONTROL_NONE); 
lcd.begin(16, 4); 
  Serial.begin(115200); 
  lcd.clear();
  gxAdcChip.begin(SCK1, MOSI1, MISO1, D2);
  timer.start();
  serBuf.setup();
  lcd.setCursor(0, 2);
  lcd.print("LCD INITILIZING  ");
  
}

void vIsrForTimer()
{
fBatActualVolt = ((analogRead(A0) >> 2)* 0.3939);
fModuleTestBatActualVolt = (gxAdcChip.readADC(2) * 0.013);
  cnt++; 
  if (cnt >= 5)
    {
      gxThermistorTh1.read();
      
      gxThermistorTh2.read();
      cnt = 0;

    }
}

// loop() runs over and over again, as quickly as it can execute.
void loop() {
  // The core of your code will likely live here.
}


Are both your LCD display and ADC using the same SPI port? Make sure both libraries are using SPI transactions to guard against the other thread (timer) from interrupting SPI operations.

For ADC chip only we are using SPI. For LCD we are using pin as GPIO only as parallel interface.

I see now, I missed that in the initialization section.

Are you using software SPI on Adafruit_MCP3008? If so, you should switch it to using hardware SPI.

However the actual problem may be that the timer is interrupting LCD operations, which I presume are running on the main thread. Since you’re using some sort of bit-banging protocol it might be affecting the LCD protocol timing, which is why the display isn’t working. You may need to use a mutex.

Yes correct, we are using software SPI. Actually we must have to use one of SPI CS pin as PWM otherwise need to add one PWM chip so for that reason we have to use software SPI.

And for software SPI CS pin we are using MCP23017 GPIO pin (I2C interface). Do you think that could be issue for LCD operation?

If I change timer time to 10/100 ms instead of 1 ms then everyting works fine.

Yes LCD display operation are in main thread. But same code is working great in P1. Only change P1 to P2 migration is ,

  • In P1 we are using inbuilt GPIO pin for SPI CS
  • In P2 we are using I2C expander chip GPIO pin for SPI CS.

You can use any GPIO for SPI CS pins, so you can still use hardware SPI if that’s the only reason.

One difference is that the GPIO on the RTL8721D is really slow. If you switch to hardware SPI it may help.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.