Serial1 works on Photon but not Argon?

I have a program communicating with a 3.5 inch 4D Systems LCD via the TX & RX lines on a Photon.

When I try to run this same program on 2 different Argon’s using the TX & RX lines I see zero activity on those TX & RX lines on the Argons for some reason? I’m using a Saleae to watch the UART lines.

Shouldn’t Serial1 work on the Argon the same as it works on the Photon?

Any known issues I should know about?

I’m sure the correct program is being loaded to the Argon so that’s not the problem.

I’m guessing worst case is that I can try a Software Serial library but would like to get Hardware UART working if possible.

There is no SoftSerial library for Particle Gen3 I know of.

The easiest way to test functionality of Serial1 is with a jumper wire between RX and TX and reading back on RX what you send yourself via TX.

1 Like

I’ve Googled for some ECHO TX/RX code for testing but if you have something you could share real quick I will put it to the test and report back.

I’m getting nothing out the Argon’s TX/ RX ports while on the same code on the Photon has those pins active as hell. Kinda weird.

This should do

SYSTEM_MODE(MANUAL)

void setup() {
  int baudrate = 115200; // default
  Serial.begin();
  Serial1.begin(baudrate);
  while(Serial.read()  >= 0);                         // flush Serial  input buffer
  while(Serial1.read() >= 0);                         // flush Serial1 input buffer
}

void loop() {
  while(Serial1.available())
    Serial.write(Serial1.read());
  
  Serial1.println("test");
  delay(100);
}

Yep that works :thinking:

Here is the code I using to setup Serial1 for the 4D Systems display and it works just fine on the Photon. I get zero pulses on the TX line when running this same code on the Argon.

Any ideas?

#include "application.h"
#include "VisiGenieSpark.h"
SYSTEM_THREAD(ENABLED);
//SYSTEM_MODE(MANUAL);



// This Demo communicates with a 4D Systems Display, configured with ViSi-Genie, utilising the Genie Arduino Library - https://github.com/4dsystems/ViSi-Genie-Arduino-Library.
// The display has a slider, a cool gauge, an LED Digits, a string box and a User LED.
// The program receives messages from the Slider0 object using the Reported Events. This is triggered each time the Slider changes on the display, and an event
// is genereated and sent automatically. Reported Events originate from the On-Changed event from the slider itself, set in the Workshop4 software.
// Coolgauge is written to using Write Object, and the String is updated using the Write String command, showing the version of the library.
// The User LED is updated by the Arduino, by first doing a manual read of the User LED and then toggling it based on the state received back.

// As the slider changes, it sends its value to the Arduino (Arduino also polls its value using genie.ReadObject, as above), and the Arduino then
// tells the LED Digit to update its value using genie.WriteObject. So the Slider message goes via the Arduino to the LED Digit.
// Coolgauge is updated via simple timer in the Arduino code, and updates the display with its value.
// The User LED is read using genie.ReadObject, and then updated using genie.WriteObject. It is manually read, it does not use an Event.

// This demo illustrates how to use genie.ReadObject, genie.WriteObject, Reported Messages (Events), genie.WriteStr, genie.WriteContrast, plus supporting functions.

// Application Notes on the 4D Systems Website that are useful to understand this library are found: http://www.4dsystems.com.au/appnotes
// Good App Notes to read are:
// 4D-AN-P4017 - Connecting a 4D Display to an Arduino Host - http://www.4dsystems.com.au/downloads/Application-Notes/4D-AN-P4017_R_1_0.zip
// 4D-AN-P4018 - Writing to Genie Objects Using an Arduino Host - http://www.4dsystems.com.au/downloads/Application-Notes/4D-AN-P4018_R_1_0.zip
// 4D-AN-P4019 - A Simple Digital Voltmeter Application using an Arduino Host - http://www.4dsystems.com.au/downloads/Application-Notes/4D-AN-P4019_R_1_0.zip
// 4D-AN-P4025 - Arduino Danger Shield for Sparkfun Danger Shield - http://www.4dsystems.com.au/downloads/Application-Notes/4D-AN-P4025_R_1_0.zip

Genie genie;
#define RESETLINE D4  // Change this if you are not using an Arduino Adaptor Shield Version 2 (see code below)

void setup()
{

  // NOTE, the genieBegin function (e.g. genieBegin(GENIE_SERIAL_0, 115200)) no longer exists.  Use a Serial Begin and serial port of your choice in
  // your code and use the genie.Begin function to send it to the Genie library (see this example below)
  // 200K Baud is good for most Arduinos. Galileo should use 115200.

  Serial1.begin(115200);  // Serial1 @ 200000 (200K) Baud / 115200 for Argon. 
  genie.Begin(Serial1);   // Use Serial1 for talking to the Genie Library, and to the 4D Systems display using Particle Photon.


  genie.AttachEventHandler(myGenieEventHandler); // Attach the user function Event Handler for processing events

  // Reset the Display
  // If NOT using a 4D Arduino Adaptor, digitalWrites must be reversed as Display Reset is Active Low, and
  // the 4D Arduino Adaptors invert this signal so must be Active High.
  
  pinMode(D7, OUTPUT);  // Set D4 on Particle Photon
  digitalWrite(D7, 1);  // Reset the Display via D4
  delay(2000);
  digitalWrite(D7,0);
  delay(2000);
  digitalWrite(D7,1);
  
  pinMode(RESETLINE, OUTPUT);  // Set D4 on Particle Photon
  digitalWrite(RESETLINE, 0);  // Reset the Display via D4
  delay(500);
  digitalWrite(RESETLINE, 1);  // unReset the Display via D4

  delay (3500); //let the display start up after the reset (This is important) *3500 Orginally

  //Turn the Display on (Contrast) - (Not needed but illustrates how)
  genie.WriteContrast(15); // 1 = Display ON, 0 = Display OFF.
  //For uLCD43, uLCD-70DT, and uLCD-35DT, use 0-15 for Brightness Control, where 0 = Display OFF, though to 15 = Max Brightness ON.
  //delay(1000);
  //Write a string to the Display to show the version of the library used
  genie.WriteStr(0, GENIE_VERSION);
}

void loop()
{

  static long waitPeriod = millis();
  static int gaugeAddVal = 1;
  static int gaugeVal = 0; //50 Default

  genie.DoEvents(); // This calls the library each loop to process the queued responses from the display

  if (millis() >= waitPeriod)
  {
    // Write to CoolGauge0 with the value in the gaugeVal variable
    genie.WriteObject(GENIE_OBJ_COOL_GAUGE, 0x00, gaugeVal);
    genie.WriteObject(GENIE_OBJ_SCOPE, 0x02, gaugeVal);
    genie.WriteObject(GENIE_OBJ_ISMARTGAUGE, 0x00, gaugeVal);


    gaugeVal += gaugeAddVal;
    if (gaugeVal == 99) gaugeAddVal = -1;
    if (gaugeVal == 0) gaugeAddVal = 1;

    // The results of this call will be available to myGenieEventHandler() after the display has responded
    // Do a manual read from the UserLEd0 object
    genie.ReadObject(GENIE_OBJ_USER_LED, 0x00);
    genie.ReadObject(GENIE_OBJ_SLIDER, 0x00);
    waitPeriod = millis() + 5; // rerun this code to update Cool Gauge and Slider in another 50ms time.
  }
}

/////////////////////////////////////////////////////////////////////
//
// This is the user's event handler. It is called by genieDoEvents()
// when the following conditions are true
//
//		The link is in an IDLE state, and
//		There is an event to handle
//
// The event can be either a REPORT_EVENT frame sent asynchronously
// from the display or a REPORT_OBJ frame sent by the display in
// response to a READ_OBJ request.
//

/* COMPACT VERSION HERE, LONGHAND VERSION BELOW WHICH MAY MAKE MORE SENSE
void myGenieEventHandler(void)
{
  genieFrame Event;
  int slider_val = 0;
  const int index = 0;  //HARD CODED TO READ FROM Index = 0, ie Slider0 as an example

  genieDequeueEvent(&Event);

  //Read from Slider0 for both a Reported Message from Display, and a Manual Read Object from loop code above
  if (genieEventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_SLIDER, index) ||
    genieEventIs(&Event, GENIE_REPORT_OBJ,   GENIE_OBJ_SLIDER, index))
  {
    slider_val = genieGetEventData(&Event);  // Receive the event data from the Slider0
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, slider_val);     // Write Slider0 value to to LED Digits 0
  }
} */

// LONG HAND VERSION, MAYBE MORE VISIBLE AND MORE LIKE VERSION 1 OF THE LIBRARY
void myGenieEventHandler(void)
{
  genieFrame Event;
  genie.DequeueEvent(&Event);

  int slider_val = 0;

  //If the cmd received is from a Reported Event (Events triggered from the Events tab of Workshop4 objects)
  if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    if (Event.reportObject.object == GENIE_OBJ_SLIDER)                // If the Reported Message was from a Slider
    {
      if (Event.reportObject.index == 0)                              // If Slider0
      {
        slider_val = genie.GetEventData(&Event);                      // Receive the event data from the Slider0
        genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0x00, slider_val);    // Write Slider0 value to to LED Digits 0
        genie.WriteContrast(slider_val); // 1 = Display ON, 0 = Display OFF.
      }
    }
  }

  //If the cmd received is from a Reported Object, which occurs if a Read Object (genie.ReadOject) is requested in the main code, reply processed here.
  if (Event.reportObject.cmd == GENIE_REPORT_OBJ)
  {
    if (Event.reportObject.object == GENIE_OBJ_USER_LED)              // If the Reported Message was from a User LED
    {
      if (Event.reportObject.index == 0)                              // If UserLed0
      {
        bool UserLed0_val = genie.GetEventData(&Event);               // Receive the event data from the UserLed0
        UserLed0_val = !UserLed0_val;                                 // Toggle the state of the User LED Variable
        genie.WriteObject(GENIE_OBJ_USER_LED, 0x00, UserLed0_val);    // Write UserLed0_val value back to to UserLed0
      }
    }
  }

  //This can be expanded as more objects are added that need to be captured

  //Event.reportObject.cmd is used to determine the command of that event, such as an reported event
  //Event.reportObject.object is used to determine the object type, such as a Slider
  //Event.reportObject.index is used to determine the index of the object, such as Slider0
  //genie.GetEventData(&Event) us used to save the data from the Event, into a variable.
}

The TX and RX lines look like this on the Photon with everything working properly.

Here is the same code on the Argon.

At first you can see the Argon’s TX line pulse out data but then I connect the LCD Screen the same as with the Photon when it works just fine and as you can see the data stops flowing?

Any ideas?

I’m feeding the 4D Systems via the VBat pin on both the Photon and the Argon. The FTDI board keeps the logic at 3.3v.

Why would the Argon stop sending data as soon as I connect the display vs just trying to keep send it?

I tried this on 2 Argon’s. I’ll try a Boron & Xenon also if I can still program it from Visual Studio.

One difference may be the “idle” state of the respective TX lines (controller and display).

And for completeness:

  • you do have common GND?
  • your display does reliably detect the ~3.3V from the Argon as HIGH?

BTW, I’m surprised by the Channel 0 trace in your first image.
If this is supposed to show the RX line on the Argon I’d have expected this to be an exact copy of the TX trace (as they are both directly connected).