Author Topic: Arduino Due Inverted Serial  (Read 11506 times)

0 Members and 1 Guest are viewing this topic.

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Arduino Due Inverted Serial
« on: January 15, 2014, 05:35:02 am »
Hi All,

Having some problems with getting a Serial printer to work with the Arduino.

I wrote the following code and it works fine with the Arduino Uno and software serial

Code: [Select]
//This is only needed if using software serial
#include <SoftwareSerial.h>
SoftwareSerial Printer(2,3,1);


int i = 1;

void setup() {
  Printer.begin(9600);
}

void loop() {
 
  if (i == 1){
    BarcodePrint("L1","G","123456789012");
    i = 0; 
  }
}


//Printer Setup
//This function is called to setup the printer
//this is called everytime the printer is going to print
//a label. If the size of the label changes then you need to
//change that in this function.
void printersetup(){
  //Set the size of the label
  Printer.println("SIZE 50 mm, 28 mm");
  //Set the gap between labels
  Printer.println("GAP 2.5 mm, 0 mm");
  //Set the printing speed 1.5,2,3,4,5,6
  Printer.println("SPEED 2");
  //Set the printing direction
  Printer.println("DIRECTION 1,0");
  //Sets the peel fucnction to on
  //This means it only prints when there is no label in peeler
  Printer.println("SET PEEL ON");
  //Sets the country to "International English"
  Printer.println("COUNTRY 061");
  //Sets the shift of the label to print on full label 
  Printer.println("SHIFT -20");
  //Clear the image buffer for printing to start
  Printer.println("CLS");
}

//Barcode Print Function
//This function is for printing labels all you need to do is
//send the offset type, the row letter and the barcode number
//for the rib and it will format the label and print it out.
void BarcodePrint(String offset,String row,String barcode){
 
 String temp = "";
 //Run the printer setup function
 printersetup();
 //Make the string to send to the printer for the barcode
 barcode = "BARCODE 780,100,\"128\",80,2,0,2,6,3,\"" +barcode;
 barcode += "\"";
 //Make the string to send to the printer for the row
 row = "TEXT 420,180,\"1\",0,2,2,1,\""+row;
 row += "\"";
 //Print the CCworx header
 Printer.println("TEXT 600,0,\"1\",0,3,2,2,\"CCWORX\"");
 //Set it to have a black background
 Printer.println("REVERSE 540,25,120,30");
 //Print the Made in Australia
 Printer.println("TEXT 600,60,\"1\",0,1,2,2,\"MADE IN AUSTRALIA\"");
 //Only print the offset if it is not 0
 if (offset != "0"){
   //Make the string to send to the printer for the offset
   temp = "TEXT 420,100,\"1\",0,7,7,1,\"";
   temp.concat(offset);
   temp.concat("\"");
   Printer.println(temp);
 }
 //Print the Row
 Printer.println(row);
 //Print the barcode
 Printer.println(barcode);
 //Tell the printer to print one label with this information on it.
 Printer.println("PRINT 1");
}


This code works fine with Software Serial but not with normal Serial. I Tried with just using the Serial prot on the Arduino Uno just by changing the "Printer" to Serial. I can't get it to work at all. It seems to be because I had to invert the SoftwareSerial by adding the extra parameter to the SoftwareSerial Printer(2,3,1);.

I need to use this code and printer on the Arduino DUE but it doesn't have the Software Serial library so I can't use it.

Doesn't anyone know how to change the Serial port on the UNO and DUE to work inverted.

Or does anyone have another way for me to do this??

Thanks  :-+

Will using schmitt trigger inverters work??
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: Arduino Due Inverted Serial
« Reply #1 on: January 15, 2014, 06:46:49 am »
Code: [Select]
int i = 1;

void setup() {
  Serial1.begin(9600);
}

void loop() {
 
  if (i == 1){
    BarcodePrint("L1","G","123456789012");
    i = 0; 
  }
}


//Printer Setup
//This function is called to setup the printer
//this is called everytime the printer is going to print
//a label. If the size of the label changes then you need to
//change that in this function.
void printersetup(){
  //Set the size of the label
  Serial1.println("SIZE 50 mm, 28 mm");
  //Set the gap between labels
  Serial1.println("GAP 2.5 mm, 0 mm");
  //Set the printing speed 1.5,2,3,4,5,6
  Serial1.println("SPEED 2");
  //Set the printing direction
  Serial1.println("DIRECTION 1,0");
  //Sets the peel fucnction to on
  //This means it only prints when there is no label in peeler
  Serial1.println("SET PEEL ON");
  //Sets the country to "International English"
  Serial1.println("COUNTRY 061");
  //Sets the shift of the label to print on full label 
  Serial1.println("SHIFT -20");
  //Clear the image buffer for printing to start
  Serial1.println("CLS");
}

//Barcode Print Function
//This function is for printing labels all you need to do is
//send the offset type, the row letter and the barcode number
//for the rib and it will format the label and print it out.
void BarcodePrint(String offset,String row,String barcode){
 
 String temp = "";
 //Run the printer setup function
 printersetup();
 //Make the string to send to the printer for the barcode
 barcode = "BARCODE 780,100,\"128\",80,2,0,2,6,3,\"" +barcode;
 barcode += "\"";
 //Make the string to send to the printer for the row
 row = "TEXT 420,180,\"1\",0,2,2,1,\""+row;
 row += "\"";
 //Print the CCworx header
 Serial1.println("TEXT 600,0,\"1\",0,3,2,2,\"CCWORX\"");
 //Set it to have a black background
 Serial1.println("REVERSE 540,25,120,30");
 //Print the Made in Australia
 Serial1.println("TEXT 600,60,\"1\",0,1,2,2,\"MADE IN AUSTRALIA\"");
 //Only print the offset if it is not 0
 if (offset != "0"){
   //Make the string to send to the printer for the offset
   temp = "TEXT 420,100,\"1\",0,7,7,1,\"";
   temp.concat(offset);
   temp.concat("\"");
   Serial1.println(temp);
 }
 //Print the Row
 Serial1.println(row);
 //Print the barcode
 Serial1.println(barcode);
 //Tell the printer to print one label with this information on it.
 Serial1.println("PRINT 1");
}

Try using Serial 1, (so you can still program)

Yes a schmitt trigger inverter would be an ideal way to invert the bus
 

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Re: Arduino Due Inverted Serial
« Reply #2 on: January 15, 2014, 12:01:15 pm »
Tried all of the extra serial ports on the DUE. I even tried with a logic level converter from spark fun as the usart on the DUE are 3.3v.

Might try and get some Schmidt trigger inverters and see what happens.

Unless someone else comes up with a good idea.
 

Offline senso

  • Frequent Contributor
  • **
  • Posts: 951
  • Country: pt
    • My AVR tutorials
Re: Arduino Due Inverted Serial
« Reply #3 on: January 15, 2014, 01:11:10 pm »
There is a configuration bit somewhere in the UART registers that invert the UART polarity, no need to use extra parts.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Arduino Due Inverted Serial
« Reply #4 on: January 15, 2014, 02:20:16 pm »
Quote
I need to use this code and printer on the Arduino DUE but it doesn't have the Software Serial library so I can't use it.

The simplest would be to get the software serial library.

Or to write your own.

Quote
Doesn't anyone know how to change the Serial port on the UNO and DUE to work inverted.

Using a NOT or NAND gate would be another way - though it would be extremely odd if a device requires this type of transmission.

Quote
There is a configuration bit somewhere in the UART registers that invert the UART polarity,

I doubt that.
================================
https://dannyelectronics.wordpress.com/
 

Offline papo

  • Regular Contributor
  • *
  • Posts: 93
  • Country: ch
Re: Arduino Due Inverted Serial
« Reply #5 on: January 15, 2014, 06:25:25 pm »
I only had a brief look at the SAM3X/A datasheet and US_MR seems to have an INVDATA field. I never used this micro so I don't know what it does. The description sounds promising but I'm sure the devil's in the details.

Regards
Matt
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Arduino Due Inverted Serial
« Reply #6 on: January 15, 2014, 06:39:10 pm »
I don't think that you can ever invert the uart signaling (aka '1' as start-bit vs. '0').

You can easily invert the signals being transmitted (aka '1' data bit vs. '0' data bit): use the '~' operator. But the signaling remains the same.
================================
https://dannyelectronics.wordpress.com/
 

Offline papo

  • Regular Contributor
  • *
  • Posts: 93
  • Country: ch
Re: Arduino Due Inverted Serial
« Reply #7 on: January 15, 2014, 06:47:21 pm »
I don't think that you can ever invert the uart signaling (aka '1' as start-bit vs. '0').

I also think that this application is somewhat weird. I'm intrigued to ask why the printer requires this inversion. Consulting the datasheet more carefully, it says:

Quote
The data field transmitted on TXD line is inverted (voltage polarity only) compared to the value written on US_THR regis-
ter

Them referring to the data field explicitly points into direction of what you said, i.e. that this is equivalent to bitwise not. In the end, tomshirvo can probably get away with using just a transistor for the inversion, particularly since apparently a level shifter is required anyways.
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Arduino Due Inverted Serial
« Reply #8 on: January 15, 2014, 06:49:13 pm »
What type of serial printer is it? Does it have a 25 pin D-SUB connector?
Then it's for the standard RS-232 signaling. 0 = +3..+15V, 1 = -3..-15V. You need a RS-232 level converter/ driver like MAX232.
 

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Re: Arduino Due Inverted Serial
« Reply #9 on: January 15, 2014, 09:10:59 pm »
Quote
There is a configuration bit somewhere in the UART registers that invert the UART polarity, no need to use extra parts.
Quote
I only had a brief look at the SAM3X/A datasheet and US_MR seems to have an INVDATA field. I never used this micro so I don't know what it does. The description sounds promising but I'm sure the devil's in the details.

So I had a look at the data sheet and found this;

• INVDATA: INverted Data
0: The data field transmitted on TXD line is the same as the one written in US_THR register or the content read in US_RHR
is the same as RXD line. Normal mode of operation.

1: The data field transmitted on TXD line is inverted (voltage polarity only) compared to the value written on US_THR register or the content read in US_RHR is inverted compared to what is received on RXD line (or ISO7816 IO line). Inverted Mode of operation, useful for contactless card application. To be used with configuration bit MSBF.

The only problem is I have no Idea what to do with this now.

Quote
You can easily invert the signals being transmitted (aka '1' data bit vs. '0' data bit): use the '~' operator. But the signaling remains the same.

Not sure where you think I should use the '~' operator?

Quote
What type of serial printer is it? Does it have a 25 pin D-SUB connector?
Then it's for the standard RS-232 signaling. 0 = +3..+15V, 1 = -3..-15V. You need a RS-232 level converter/ driver like MAX232.

It is a Label printer TSC is the Brand and the model is TTP-245C

I purchased a sparkfun RS-232 level converter and that didn't work.
https://www.sparkfun.com/products/449

The printer uses a DB9 connector.
 

Offline papo

  • Regular Contributor
  • *
  • Posts: 93
  • Country: ch
Re: Arduino Due Inverted Serial
« Reply #10 on: January 15, 2014, 10:09:24 pm »
The only problem is I have no Idea what to do with this now.

Yeah I don't think this will help. Basically we were confused about the following: Typically, the serial protocol works as follows: The line is HIGH by default. When the transmitter is sending a byte, it first pulls the line LOW for one time unit. Then during the subsequent 8 time units, it transmits each bit, setting the line to either HIGH or LOW depending on the bit value. Lastly, the line is HIGH for another time unit. This is the stop bit and you can set up your hardware to require several stop bits or none.

In any case, it was not clear whether by inverting, you wanted to send LOW for a 1-bit and HIGH for a 0-bit, i.e. just invert the data byte, or whether you need to invert the whole thing, i.e. also have the line LOW by default, a HIGH start bit and a LOW stop bit.

Looking at the code of SoftwareSerial, the magic parameter seems to invert everything, not just the byte. I am not sure whether INVDATA inverts the byte or the whole pin logic level, but I'm tending towards the former which is not what you want.

Not sure where you think I should use the '~' operator?

The ~ operator just inverts the byte. So you could invert your byte pattern, but not the logic level of the stop bit etc.

It is a Label printer TSC is the Brand and the model is TTP-245C

The weird thing is, looking at the manual this is to be connected to a PC without any quirks. Hence I don't understand how this can possibly work when the whole logic levels are inverted.

I purchased a sparkfun RS-232 level converter and that didn't work.
https://www.sparkfun.com/products/449

Can you give us a little bit more details? Like some diagram and/or picture of how you wired the stuff together, whether you have anything connected between the arduino (the one that works) and the printer etc.? Also "it didn't work is a bit difficult to work with". I guess the printer just did not print? The reasons causing this could range from a pin mis-match to the grounds not being tied together properly. Can you tell us what kind of equipment you have to debug the problem? Worst case I'd suggest to configure one arduino as receiver with the same parameters as your printer (if you print the self-test slip, everything should be on there) and try to successfully transmit from the other one. Also make sure to meet the voltage level requirements of the printer.

Regards
Matt
 

Offline papo

  • Regular Contributor
  • *
  • Posts: 93
  • Country: ch
Re: Arduino Due Inverted Serial
« Reply #11 on: January 15, 2014, 10:16:51 pm »
Actually looking at the http://en.wikipedia.org/wiki/TIA-574#Voltage_levels, logic one is a negative voltage and the line sits at a negative voltage when idle. I had completely forgotten about that. So you really need that 232-converter. And for it to operate properly, you would set your arduino *not* to invert anything.

My best guess is that your printer interprets 0 V as a negative voltage, therefore as HIGH and the stuff works. But I'm not sure and you really should do it the proper way if you want this to be reliable.

Regards
Matt

Edit: I'm 50% percent sure you mixed up TX and RX due to Rask's comment on the Spark Fun page.
« Last Edit: January 15, 2014, 10:25:17 pm by papo »
 

Offline sync

  • Frequent Contributor
  • **
  • Posts: 799
  • Country: de
Re: Arduino Due Inverted Serial
« Reply #12 on: January 15, 2014, 10:25:23 pm »
The printer is using the standard RS-232 (high voltage) levels. You need a level converter. Have you tried a null modem cable (crossed RX - TX lines) with the sparkfun converter?
 

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Re: Arduino Due Inverted Serial
« Reply #13 on: January 15, 2014, 10:35:07 pm »
Quote
Have you tried a null modem cable (crossed RX - TX lines) with the sparkfun converter?

The only thing I didn't try.

All works now.

Thanks for all the help, it is because of communities like this that I can learn so much.  :-+
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: Arduino Due Inverted Serial
« Reply #14 on: January 15, 2014, 11:50:18 pm »
Doesn't anyone know how to change the Serial port on the UNO and DUE to work inverted.

You can feed it to an interrupt input and wire the inverted state to another output pin from an ISR.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Arduino Due Inverted Serial
« Reply #15 on: January 16, 2014, 02:04:44 am »
If you have a label printer with a DB9 connector designed to be connected directly to a PC, then it is speaking "rs232" signalling on it's serial port.

RS232 is "inverted" compared to "TTL Serial" - the "1" state (including idle) is supposed to become -3 to -15V, and the "0" state becomes +3 to +15V.  Because of the way that rs232 receivers are implemented, it USUALLY works if you just send "inverted TTL" (0V for "1", 5V for "0"), but that's not technically correct.

Quote
I purchased a sparkfun RS-232 level converter and that didn't work.
A level converted like that is the correct solution, and IMNSHO you should be debugging why you weren't able to get it to work, rather than chasing obscure uart options that aren't "right" anyway.

That particular converter seems to assume a bidirectional serial connection; it sucks the higher voltage for transmitter from the receive data signal.  This is "clever", but it won't work if you don't connect both signals, or if the devices is truly "receive only" or if both sides are trying to do the same thing, or ... other circumstances.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf