Arduino Due Inverted Serial - Page 1
Forum section: electronics / general

author: tomshirvo
author_rank: Regular Contributor
timestamp: January 15, 2014, 05:35:02 am
content: 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 serialCode://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 labelPrinter.println("SIZE 50 mm, 28 mm");//Set the gap between labelsPrinter.println("GAP 2.5 mm, 0 mm");//Set the printing speed 1.5,2,3,4,5,6Printer.println("SPEED 2");//Set the printing directionPrinter.println("DIRECTION 1,0");//Sets the peel fucnction to on//This means it only prints when there is no label in peelerPrinter.println("SET PEEL ON");//Sets the country to "International English"Printer.println("COUNTRY 061");//Sets the shift of the label to print on full labelPrinter.println("SHIFT -20");//Clear the image buffer for printing to startPrinter.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 functionprintersetup();//Make the string to send to the printer for the barcodebarcode = "BARCODE 780,100,\"128\",80,2,0,2,6,3,\"" +barcode;barcode += "\"";//Make the string to send to the printer for the rowrow = "TEXT 420,180,\"1\",0,2,2,1,\""+row;row += "\"";//Print the CCworx headerPrinter.println("TEXT 600,0,\"1\",0,3,2,2,\"CCWORX\"");//Set it to have a black backgroundPrinter.println("REVERSE 540,25,120,30");//Print the Made in AustraliaPrinter.println("TEXT 600,60,\"1\",0,1,2,2,\"MADE IN AUSTRALIA\"");//Only print the offset if it is not 0if (offset != "0"){//Make the string to send to the printer for the offsettemp = "TEXT 420,100,\"1\",0,7,7,1,\"";temp.concat(offset);temp.concat("\"");Printer.println(temp);}//Print the RowPrinter.println(row);//Print the barcodePrinter.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??ThanksWill using schmitt trigger inverters work??

author: Rerouter
author_rank: Super Contributor
timestamp: January 15, 2014, 06:46:49 am
content: Quote from: tomshirvo on January 15, 2014, 05:35:02 amTry using Serial 1, (so you can still program)Yes a schmitt trigger inverter would be an ideal way to invert the bus

author: tomshirvo
author_rank: Regular Contributor
timestamp: January 15, 2014, 12:01:15 pm
content: 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.

author: senso
author_rank: Frequent Contributor
timestamp: January 15, 2014, 01:11:10 pm
content: There is a configuration bit somewhere in the UART registers that invert the UART polarity, no need to use extra parts.

author: dannyf
author_rank: Super Contributor
timestamp: January 15, 2014, 02:20:16 pm
content: QuoteThe simplest would be to get the software serial library.Or to write your own.QuoteUsing a NOT or NAND gate would be another way - though it would be extremely odd if a device requires this type of transmission.QuoteI doubt that.

author: papo
author_rank: Regular Contributor
timestamp: January 15, 2014, 06:25:25 pm
content: 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.RegardsMatt

author: dannyf
author_rank: Super Contributor
timestamp: January 15, 2014, 06:39:10 pm
content: 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.

author: papo
author_rank: Regular Contributor
timestamp: January 15, 2014, 06:47:21 pm
content: Quote from: dannyf on January 15, 2014, 06:39:10 pmI 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:QuoteThem 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.

author: sync
author_rank: Frequent Contributor
timestamp: January 15, 2014, 06:49:13 pm
content: 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.

author: tomshirvo
author_rank: Regular Contributor
timestamp: January 15, 2014, 09:10:59 pm
content: QuoteQuoteSo I had a look at the data sheet and found this;• INVDATA: INverted Data0: The data field transmitted on TXD line is the same as the one written in US_THR register or the content read in US_RHRis 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.QuoteNot sure where you think I should use the '~' operator?QuoteIt is a Label printer TSC is the Brand and the model is TTP-245CI purchased a sparkfun RS-232 level converter and that didn't work.https://www.sparkfun.com/products/449The printer uses a DB9 connector.

author: papo
author_rank: Regular Contributor
timestamp: January 15, 2014, 10:09:24 pm
content: Quote from: tomshirvo on January 15, 2014, 09:10:59 pmYeah 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.Quote from: tomshirvo on January 15, 2014, 09:10:59 pmThe ~ operator just inverts the byte. So you could invert your byte pattern, but not the logic level of the stop bit etc.Quote from: tomshirvo on January 15, 2014, 09:10:59 pmThe 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.Quote from: tomshirvo on January 15, 2014, 09:10:59 pmCan 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.RegardsMatt

author: papo
author_rank: Regular Contributor
timestamp: January 15, 2014, 10:16:51 pm
content: Actually looking at thehttp://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.RegardsMattEdit: I'm 50% percent sure you mixed up TX and RX due to Rask's comment on the Spark Fun page.

author: sync
author_rank: Frequent Contributor
timestamp: January 15, 2014, 10:25:23 pm
content: 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?

author: tomshirvo
author_rank: Regular Contributor
timestamp: January 15, 2014, 10:35:07 pm
content: QuoteThe 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.

author: zapta
author_rank: Super Contributor
timestamp: January 15, 2014, 11:50:18 pm
content: Quote from: tomshirvo on January 15, 2014, 05:35:02 amYou can feed it to an interrupt input and wire the inverted state to another output pin from an ISR.

author: westfw
author_rank: Super Contributor
timestamp: January 16, 2014, 02:04:44 am
content: 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.QuoteA 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.