system
March 13, 2015, 11:52am
1
Hi All,
I'm new here, used to using an Uno, but have now purchased a Due (for the extra serial ports and 3.3V operation).
I'm using the Due Serial port (for debug) and Serial2 for communication with an IC. The IC requires that the TX line is pulled low for 2ms then return to high for 10ms before the start of a transmission sequence.
To do this, I have implemented the function below - this turns pin 16 into a digital pin temporarily, before restarting the serial communications after the initiation sequence.
The problem I have, is that after turning into a digital port, the Serial2 comms never starts working again (the line remains high).
Any help with this would be greatly appreciated.
void sendMessageData(char ID, char data1, char data2, char data3, char data4, char checksum) {
int count = 0;
Serial2.end();
pinMode(16,OUTPUT);
digitalWrite(16,LOW);
delay(2);
digitalWrite(16,HIGH);
delay(10);
Serial2.begin(9600);
lastChar[count] = 0x55;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = ID;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data1;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data2;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data3;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data4;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = checksum;
Serial2.write(lastChar[count]);
}
Thanks,
Dave.
Hi Dave, welcome to the forum,
Have you tried to leave out the following code and see what happens?
pinMode(16,OUTPUT);
You could also try just setting your serial2.begin only once in setup() as per normal and have:
int count = 0;
digitalWrite(16,LOW);
delay(2);
digitalWrite(16,HIGH);
delay(10);
lastChar[count] = 0x55;
.
.
Just thoughts that came to my mind which may be worth a try.
Paul
system
March 13, 2015, 1:53pm
3
Hi Paul, Thanks for your response.
I have tried both of the above methods and both have the same effect - the serial message gets sent, but not the initialisation sequence. This means that the chip doesn't respond to the messages.
If it helps, I've attached the full code below - the checkIncoming() function is probably not working yet as I haven't managed to receive proper data yet.
#define en 14
char lastChar[7];
char readChar[7];
boolean newChar = false;
void setup() {
//pinMode(16,OUTPUT);
Serial.begin(9600);
Serial2.begin(9600);
pinMode(en,OUTPUT);
}
void loop() {
digitalWrite(en,HIGH);
while(Serial.available()) {
//Serial2.write(0x55);
//TX1 MESSAGE
//sleep
sendMessageData(0x3C, 0, 0, 0, 0, 0xFF);
delay(10);
checkIncoming();
//wake up / send message
sendMessageData(0xE9, 0x88, 0x00, 0x00, 0x01, 0x76); //14V
delay(10);
checkIncoming();
sendMessageNoData(0x55); //read TX3
delay(10);
checkIncoming();
Serial.read(); //clear the buffer
}
}
void sendMessageData(char ID, char data1, char data2, char data3, char data4, char checksum) {
int count = 0;
Serial2.end();
pinMode(16,OUTPUT);
digitalWrite(16,LOW);
delay(2);
digitalWrite(16,HIGH);
delay(10);
//pinMode(16,INPUT);
Serial2.begin(9600);
lastChar[count] = 0x55;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = ID;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data1;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data2;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data3;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = data4;
Serial2.write(lastChar[count]);
count++;
lastChar[count] = checksum;
Serial2.write(lastChar[count]);
}
void sendMessageNoData(char ID) {
Serial2.end();
digitalWrite(16,LOW);
delay(2);
digitalWrite(16,HIGH);
delay(10);
Serial2.begin(9600);
lastChar[0] = 0x55;
Serial2.write(lastChar[1]);
lastChar[1] = ID;
Serial2.write(lastChar[1]);
lastChar[2] = 0;
lastChar[3] = 0;
lastChar[4] = 0;
lastChar[5] = 0;
lastChar[6] = 0;
}
void checkIncoming() {
int counter = 0;
while (Serial2.available()) {
//Serial.println("Serial 2 Available");
readChar[counter] = Serial2.read();
//Serial.println(readChar[counter]);
if (readChar[counter] != lastChar[counter])
{
newChar = true;
Serial.println(readChar[counter]);
}
else
{
newChar = false;
}
counter++;
}
counter = 0;
}
dlloyd
March 13, 2015, 2:17pm
4
If your IC can tolerate 2ms low and 12ms high prior to transmission, then you could use this:
Serial2.begin(500, SERIAL_5N1); //2ms per bit
Serial2.write(0xFF); //low 2ms (start bit), high 12ms (5 bits + stop bit)
Serial2.begin(9600); //uses SERIAL_8N1 (default)
What is the IC you're using?
system
March 13, 2015, 2:49pm
5
Hi,
I have figured a way to get this working, with a very minor change to the hardware. What I've done is connected the TX pin through a 4k7 resistor to another pin (pin 15 configured as input). Pin 15 is then connected to the RX pin of the IC.
When I want to do the initiation sequence, I set the 2nd pin as an output do the low/high sequence, then return it to an input. From there, the Tx will pass through the resistor to the RX of the IC. Code below:
pinMode(initPin,OUTPUT);
digitalWrite(initPin,LOW);
delay(2);
digitalWrite(initPin,HIGH);
delay(10);
pinMode(initPin,INPUT);
where initPin is defined as pin 15.
Just for completion sake, I tested the suggestion above and this too seemed to work.
Thanks everyone!
dlloyd
March 14, 2015, 3:14am
6
This method uses direct register programming and doesn't require any hardware changes:
REG_PIOA_PER |= (0x01 << 13); //enable GPIO use for pin 16
REG_PIOA_OER |= (0x01 << 13); //set pin 16 as OUTPUT
REG_PIOA_CODR |= (0x01 << 13); //set pin 16 LOW
delay(2);
REG_PIOA_SODR |= (0x01 << 13); //set pin 16 HIGH
delay(10);
REG_PIOA_PDR |= (0x01 << 13); //enable peripheral use for pin 16
dlloyd wrote:
direct register programming
I'll tinker and expand with that bit of code for my own playing, thanks for that