Serial1 UART on P1

I had some code where my P1 communicates with an ATMega8 over UART. This code was working for quite a while but stopped working… I’m guessing I had my firmware compiled against an older version than 0.6.2.

Anyways, my code looks something like this:

#define EXPANSION_BOX_PIN A0

void setup () {
    Serial.begin(115200);
	Serial1.begin(19200);

	pinMode(EXPANSION_BOX_PIN, OUTPUT);
}

void main () {
  digitalWrite(EXPANSION_BOX_PIN, HIGH);
  Serial1.write('+');
  Serial1.write('+');
  Serial1.flush();
  digitalWrite(EXPANSION_BOX_PIN, LOW);

  delay(100);

  uint8_t data = 0;
  while (Serial1.available() > 0) {
    data = Serial1.read();			
 	Serial.println(data);
  }
}

Does this all look OK? I’m so confused as to what isn’t working.

You need a Serial.begin() as well?

Yeah, I’ve updated my question.

My source I’m working with is a lot more complicated in how the data is sent but this is the general flow.

You might want to perform a loopback test to see if that works first…

I used a Photon recently with a Pi Zero and the Uart worked fine on Serial for me.

That might be a bit difficult as this is a custom PCB + RJ12 port. I’m going to have my EE look at it with his tools and see if data is even being sent over the wire.

So I’m seeing something weird…

I started sending from the ATMega and I am seeing data come in but it’s always a bunch of zeros. If I change the baud rate sometimes I see 0x80.

So communication works, but for some reason the data is incorrect.

Just to be clear – this exact code was working a month ago.

in your setup code i see serial1.begin(115200),(19200) at 2 baud rates or maybe you copied it incorrectly

Just for clarification, the USB Serial does not care about the set baud rate as it’s only a virtual serial port which always uses the set USB transfer rate and not the rate provided via Serial.begin(). In the more recent system versions this is also evident by the fact that there is an overload of Serial.begin() that does not take any baudrate at all.
And in addidtion with the standard system firmware, you won’t even need Serial.begin() at all since the system already does that by default.

However, having Serial.begin() with baudrate doesn’t harm and can be considered good practice since it’ll work with all system versions.

About the RJ12 you could just fix a loop-back test cable that feeds TX back to RX.

Doh… yeah, that’s supposed to be Serial/Serial1

Thanks @ScruffR

So I built a cable to feed TX into RX but I'm still seeing the issue. It looks like my circuit isn't sending for some reason. That said, I know with 100% certainty that this code worked in the past. I also tried using 0.5.3 system firmware on one of my PCBs.

Here's the actual code I was running for testing.

#include "application.h"

/*maximum size of incoming packet from ext board*/
#define PACKET_BUFFER	64

/*array for outging packet*/
uint8_t dataPacket[16];

/*array for incoming packet*/
uint8_t incomingBuffer[PACKET_BUFFER];

/*process and send packet*/
void UartSendPacket(uint8_t* pstr, int length)
{
	uint8_t * str = pstr;  //.. str = pstr
	int i = 0;

	/*packet needs to start with the start-of-packet byte (ASCII '+' value)*/
	Serial1.write('+');

Serial.println("SEND");
	while((i < length)) 												/* Loop through the packet data bytes */
	{

		/*if any of the special bytes are found, escape them by sending ASCII '#' before the byte*/
		if( (*str == '*' || *str == '+' || *str == '-' || *str == '#'))
		{
			Serial1.write('#');
		}

		/*send data byte*/
		Serial1.write(*str);
		Serial.print(*str, HEX);
				 Serial.print(" ");

		str++;														/* Point to next char */
		i++;														/* Incr length index */
	}
	Serial.println("");
	Serial.println("SEND END");

	/*packet needs to end with the end-of-packet byte (ASCII '-' value)*/
	Serial1.write('-');

	/*wait for serial data to be transfered*/
	Serial1.flush();
}

/*data packet preparation*/
void PrepareDataPacket(void)
{

	uint8_t checksum = 0;
	uint8_t i;

	dataPacket[0] = 0x01;	/*destination - hardcoded 0x01*/
	dataPacket[1] = 0x00;	/*source - mainboard*/
	dataPacket[2] = 0x22; /*packet type - solenoid control */

	/*dataPacket[3] - turn solenoid ON
	Bits: 0x03 - solendoid 1
	Bits: 0x0C - solendoid 2
	Bits: 0x30 - solendoid 3
	Bits: 0xC0 - solendoid 4

	solendoid will turn OFF automatically when no more flow is detected*/
	dataPacket[3] = 0x00;

	/*dataPacket[4] - force solenoid OFF
	Bits: 0x03 - solendoid 1
	Bits: 0x0C - solendoid 2
	Bits: 0x30 - solendoid 3
	Bits: 0xC0 - solendoid 4
	Thus can be used to override the auto-off algorithm, for example in case abnormal flow is detected (tap left open or leak)
	*/
	dataPacket[4] = 0x00;

	/*calculate checksum*/
	for(i = 0; i<5; i++)
	{
		checksum ^= dataPacket[i];
	}

	dataPacket[5] = 255 - checksum;
}

void setup(void)
{
	Serial.begin();
	Serial1.begin(19200);

	/*RS485 direction pin*/
	pinMode(A0, OUTPUT);

  Serial.println("STARTING");

}

void loop(void)
{
	uint8_t i, count = 0,checksum = 0, data = 0, esc_flag = 0, isValid =0;

	/*preare the data packet*/
	PrepareDataPacket();

	/*set RS485 direction pin HIGH: transmitter*/
	digitalWrite(A0,HIGH);
	/*transmit packet*/
	UartSendPacket(dataPacket,6);
	/*set RS485 direction pin LOW: receiver*/
	digitalWrite(A0,LOW);

	/*small delay - in the real firmware the receive side should be implemented with interrupts to avoid blocking*/
	delay(100);

	/*read all received bytes*/
	while (Serial1.available() > 0) {

			data = Serial1.read();			/* Get data */
			Serial.print(data, HEX);
			     Serial.print(" ");
			if(data == '#' && !esc_flag)				/* If finding first escape byte */
			{
				esc_flag = 1;							/* Set escape byte flag */
			}
			else
			{
				if(!esc_flag)							/* Escape byte not set */
				{
					if(data == '+')						/* Getting sync byte of packet, since no escape byte beore it */
					{
						count = 0;						/* Reset Counter - since start of packet */
						for(i=0; i<PACKET_BUFFER; i++)
						{
							incomingBuffer[i] = 0;	/* Clearing packet buffer */
						}

						continue;
					}

					if(data == '-')						/* End of packet */
					{
						checksum = 0;					/* Reset checksum */

						for(i=0; i<(count-1); i++)		/* Calculating checksum of packet */
						{
							checksum ^= incomingBuffer[i];
						}

						checksum = 255 - checksum;

						if(checksum == incomingBuffer[count - 1])
						{
							isValid = 1;	/*packet is valis*/
						}
						else
						{
							isValid = 0;			/* packet invalid */
						}
					}

				}
				else
				{
					esc_flag = 0;
				}


				if(count < PACKET_BUFFER)						/* If count still less than packet buffer size */
				{
					incomingBuffer[count] = data;	/* Store data in buffer */
					count++;									/* Increment counter */
				}

			}
		}

		if(isValid)
		{
			/*print received data to USB*/
			if( (incomingBuffer[0] == 0x00) && (incomingBuffer[1] == 0x01) && (incomingBuffer[2] == 0x33) )
			{
					Serial.printf("SOL1: %s, PULSES1: %d, SOL2: %s, PULSES2: %d, SOL3: %s, PULSES3: %d, SOL4: %s, PULSES4: %d\n",
																																									(incomingBuffer[3] & 0x01)?"ON":"OFF",	/*solenoid 1*/
																																									(incomingBuffer[4]<<24) | (incomingBuffer[5]<<16) |	(incomingBuffer[6]<<8) | (incomingBuffer[7]), /*flow 1*/
																																									(incomingBuffer[3] & 0x02)?"ON":"OFF",	/*solenoid 2*/
																																									(incomingBuffer[8]<<24) | (incomingBuffer[9]<<16) |	(incomingBuffer[10]<<8) | (incomingBuffer[11]), /*flow 2*/
																																									(incomingBuffer[3] & 0x04)?"ON":"OFF",	/*solenoid 3*/
																																									(incomingBuffer[12]<<24) | (incomingBuffer[13]<<16) |	(incomingBuffer[14]<<8) | (incomingBuffer[15]), /*flow 3*/
																																									(incomingBuffer[3] & 0x08)?"ON":"OFF",	/*solenoid 4*/
																																									(incomingBuffer[16]<<24) | (incomingBuffer[17]<<16) |	(incomingBuffer[18]<<8) | (incomingBuffer[19])); /*flow 4*/

			}
		}

		delay(1000);
}

Ok, I’ve done a bit more digging.

According to the docs, these are the correct pins:

63	MICRO_UART1_RXD	PA10	RX
64	MICRO_UART1_TXD	PA9	    TX

When I do a Serial.println(RX); and Serial.println(TX) I get 18 and 19.

Are the docs incorrect and the pin numbers changed?

The pin numbers don’t translate directly to the hardware port/GPIO labels.

18/19 are the correct numbers which could be used for pinMode() for instance, just as you’d use RX/TX.
But these numbers haven’t got any relation to the pin numbers on the P1 package - for your PCB you need to go with the hardware labels.