How do I send Baudot shift to letters and shift to figures (using Serial port and paper tape punch)

Hi everyone. This is a long shot but I am writing a program to control an old Siemens paper tape punch reader. The punch is set for 5 hole paper tape and punches/reads Baudot code. I am communicating with the machine via serial. I have set up a switch/case statement that reads keypresses and punches the characters according to Baudot protocol BUT I have a problem working out how to punch the characters that change the punch mode from letter mode to figure/punctuation mode. Basically I need to be able to punch the number 27 when switching from letters to figures and the number 31 when changing back. So say I punch "Hello I am 41 years old", the punch would punch the letters and when it got to 41 it would punch the 27 before 41 and then when it had punched the 1 of 41 it would then see we had gone back to letters and punch a 31... does this make sense? Has anyone worked with writing code for baudot machines?

Any help or pointers/tips would be great. Thanks,

Steve.

Tagged:

Answers

  • This is just an idea. Would that do the trick for you?

    Kf

    final String NUMBER_MODE="27";
    final String ALPHABET_MODE="31";
    boolean numberMode=false;
    String message="";
    
    void setup(){
       size(300,200);
       textAlign(CENTER,CENTER);
       fill(255,255,0);
       message="";
    
    }
    
    void draw(){
      background(0);
      text(message,width/2,height/2);
    }
    
    void keyPressed(){
    
       if(key>='0' && key<='9'){
          if(numberMode==false){
              //Begin of typing numbers... switch to number mode
              //stitch char sequence to change into number mode
              message+=NUMBER_MODE;
              numberMode=true;
          }
          message+=key; 
       }
       else{
          if(numberMode==true){
              //Finished typing numbers... now switch to alphabet mode
              //stitch char sequence to change into alphabet mode
              message+=ALPHABET_MODE;
              numberMode=false;
          }
          message+=key;
       }
    }
    
  • edited December 2016

    @kfrajer's approach looks right to me.

    If you aren't doing live typing you can also wrap this approach in a function that takes a String and returns a String. Here is a simple example of a function that uses StringBuilder to do it all at once -- it reads the string backwards rather than forward to make inserting safer and more versatile.

    /** 
     * Baudot Paper Tape Encoding
     * 
     * Click to add alpha/num transition codes to string.
     * 
     * @ author Jeremy Douglass
     * @ since 2016-11-28
     * Processing 3.2.3
     * 
     * Based on sketch by kfrajer
     * 
     * Discussion
     * https:// forum.processing.org/two/discussion/19352/how-do-i-send-baudot-shift-to-letters-and-shift-to-figures-using-serial-port-and-paper-tape-punch#latest
     */
    
    import java.lang.*;
    
    final String NUMBER_MODE="27";
    final String ALPHABET_MODE="31";
    String message;
    
    void setup(){
       size(300,200);
       textAlign(CENTER,CENTER);
       message = "Hello I am 41 years old";
    }
    
    void draw(){
      background(0);
      text(message,width/2,height/2);
    }
    
    void mouseClicked(){
      message = baudoter(message);
    }
    
    String baudoter (String str_){
      StringBuilder str = new StringBuilder(str_);
      boolean numMode = false;
      char c1 = str.charAt(str.length()-1);
      if(c1 >='0' && c1 <='9'){
        numMode = true;
      }
      for(int i = str.length()-1; i > 0 ; i--){
        c1 = str.charAt(i);
        if(c1>='0' && c1<='9'){
          if(!numMode){
            str.insert(i+1, ALPHABET_MODE);
            numMode = true;
          }
        } else {
          if(numMode){
            str.insert(i+1, NUMBER_MODE);
            numMode = false;
          }
        }
      }
      return str.toString();
    }
    
  • Hi guys and thanks for the help! This is invaluable. jeremydouglass your code is excellent however I am doing live typing so I think kfrajer's code is what I'm looking for. Could you possibly help me on how I would include punctuation keys in the number shift code as well? Thanks, Steve. :)

  • edited November 2016

    If the distinction is between "a letter" and "not a letter" then try this line from the Processing Keyboard Functions example:

    if((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) {
      // a letter
    } else {
      // anything else
    }
    

    Java also has Character.isDigit(), Character.isLetter(), and Character.isLetterOrDigit(), so you could also check this way and then punctuation would be "anything else." Or you could enumerate the allowed punctuation marks you are looking for, and check to see if the typed key is found in that list (String, Hashmap, whatever).

  • edited November 2016

    If we don't care about whether a character is lower or upper case, just use keyCode instead of key: *-:)

    final int k = keyCode;
    if (k >= 'A' && k <= 'Z') {}
    
  • Hi guys, back again. OK I've implemented kfrajer's code into my program. The text window works as in the example but I now want to punch the message a character at a time. I've used a for loop and attempted using .charAt to send the chars of the string to the punch one at a time. It does but charAt doesn't punch the 27 or the 31 for the number and letter shifts. Any ideas why not? I've included the code:

    `void keyPressed() { vals=key;

    char aChar=0; checkVal=int(vals);

    if (checkVal >=33 && checkVal <=63 || checkVal==172) { if ( pltrue==false) { message+=NUMBER_MODE; pltrue=true;

    } punchFigs(); message+=pchar; }

    else{ if( pltrue==true) { message+=ALPHABET_MODE; pltrue=false; } punchLets(); message+=pchar; } for (int index=0;index <( message.length());index++) { aChar=message.charAt(index); } // myPort.write(aChar); print(aChar); }

    void punchLets() {

    //println(checkVal); switch (vals) { case 'a': pchar=lets[3]; break;

    case 'b': pchar=lets[25]; break;

    case 'c': pchar=lets[14]; break;

    case 'd': pchar=lets[9]; break;

    case 'e': pchar=lets[1]; break;

    case 'f': pchar=lets[13]; break;

    case 'g': pchar=lets[26]; break;

    case 'h': pchar=lets[20]; break;

    case 'i': pchar=lets[6]; break;

    case 'j': pchar=lets[11]; break;

    case 'k': pchar=lets[15]; break;

    case 'l': pchar=lets[18]; break;

    case 'm': pchar=lets[28]; break;

    case 'n': pchar=lets[12]; break;

    case 'o': pchar=lets[24]; break;

    case 'p': pchar=lets[22]; break;

    case 'r': pchar=lets[10]; break;

    case 's': pchar=lets[5]; break;

    case 't': pchar=lets[16]; break;

    case 'u': pchar=lets[7]; break;

    case 'v': pchar=lets[30]; break;

    case 'w': pchar=lets[19]; break;

    case 'x': pchar=lets[29]; break;

    case 'y': pchar=lets[21]; break;

    case 'z': pchar=lets[17]; break;

    case ' ': pchar=lets[4]; break;

    case '\n': pchar=lets[2]; break;

    case '\r': pchar=lets[8]; break;

    } // message+=pchar;

    }

    void punchFigs() {

    //println(checkVal); switch (vals) { case '-': pchar=figs[3]; break;

    case '?': pchar=figs[25]; break;

    case ':': pchar=figs[14]; break;

    case '\b': pchar=figs[9]; break;

    case '3': pchar=figs[1]; break;

    case '!': pchar=figs[13]; break;

    case '&': pchar=figs[26]; break;

    case '$': pchar=figs[20]; break;

    case '8': pchar=figs[6]; break;

    case '|': pchar=figs[11]; break;

    case '(': pchar=figs[15]; break;

    case ')': pchar=figs[18]; break;

    case '.': pchar=figs[28]; break;

    case ',': pchar=figs[12]; break;

    case '9': pchar=figs[24]; break;

    case '0': pchar=figs[22]; break;

    case '4': pchar=figs[10]; break;

    case '`': pchar=figs[5]; break;

    case '5': pchar=figs[16]; break;

    case '7': pchar=figs[7]; break;

    case ';': pchar=figs[30]; break;

    case '2': pchar=figs[19]; break;

    case '/': pchar=figs[29]; break;

    case '6': pchar=figs[21]; break;

    case '+': pchar=figs[17]; break;

    case ' ': pchar=figs[4]; break;

    case '\n': pchar=figs[2]; break;

    case '\r': pchar=figs[8]; break;

    }`

    thanks again for the help guys

  • It does but charAt doesn't punch the 27 or the 31 for the number and letter shifts.

    Sorry it is not clear what you mean with punch 27 or 31. Do you want to stream them as each value as two different characters or as a single ascii value?

    Kf

  • the 27 gets added to the string if i switch from letters to numbersor punctuation and 31 gets added to the string if i change back i.e. : "hello my name is steve I am (27)41(31) years old(27). if i output the "message" string as text it shows the changeover as per your code. but when i use the .aChar in the for loop to break down the string into indvidual chars to be sent to the punch, I dont see the 27 or 31 characters. the for loop looks like this:

    for (int index=0;index <( message.length());index++) { aChar=message.charAt(index); } // myPort.write(aChar); print (aChar); }

    the print(aChar); displays the letters and characters but not the shift numbers which also don't get sent to the punch although everything else does.

  • Please format your code above. Edit your post, select your code and hit ctrl+o. Ensure there is an empty line above and below your code. Related to your question, it is important to see all the code. If 27 and 31 were included it in the message properly, then your for loop should display them. I have a feeling you are not using the right String "message" object. This is the reason why it is important to see all your formatted code.

    Kf

  • `import processing.serial.*; import arb.soundcipher.*;

    Serial myPort;  // Create object from Serial class
    
    int x,y;
    int val,val2,checkVal;      // Data received from the serial port
    char letter,figure, nextChar, tmp;
    char[] buffer;
    char vals;
    char buff;
    char character,pchar, pchar2;
    char[] lets={'\0','e','\n','a',' ','s','i','u','\r','d','r',
    'j','n','f','c','k','t','z','l','w','h','y','p','q','o','b',
    'g',27,'m','x','v',31};
    
    char[] figs={'\0','3','\n','-',' ','`','8','7','\r','?','4',
    '`',',','!',':','(','5','+',')','2','$','6','0','1','9','?',
    '&',27,'.','/',';',31};
    
    
    
    boolean ltrue;  //are we reading letters or numbers?
    boolean pltrue=false;  //are we punching letters? 
    final String NUMBER_MODE="27";
    final String ALPHABET_MODE="31";
    
    String message="";
    
    
    void setup() 
    {
      size(1000,400);
      textAlign(CENTER,CENTER);
      fill(255,75,0);
      background(0);
    
    x=4;
    y=50;   // text co ords -- unused
    buffer=new char[32];  // unused 
    // Create the font
     textFont(createFont("MQ9LiquidCrystalText-24",24));
    
      String portName = Serial.list()[0];
      myPort = new Serial(this, portName, 300,'N',5,1.0);
      message="";
     }
    
    void draw()
    {
    background(0);
    text(message,width/2,height/2);
     read();  // paper tape reader
     }
    
    void read()    //paper tape reader function
    {
    if ( myPort.available() > 0) { 
    
    val=myPort.read();
    if ( val==31)
    {
    ltrue=true;
    
     }
     if (val==27 )
     {
      ltrue=false;
    
    }
    
     if (ltrue==false)
     {
     character=figs[val];
     }
     if (ltrue==true)
      {
      character=lets[val];
     }
     if (character !=27 && character !=31)
     {
     print(character);
     message+=character;
    
     }
     else
      {
      print(); 
     }
    }
    }
    
    void keyPressed()
    {
     vals=key;
    
     char aChar=0;
     checkVal=int(vals);
    
    if (checkVal >=33 && checkVal <=63 || checkVal==172)
     {
     if ( pltrue==false)
      {
      message+=NUMBER_MODE;
     pltrue=true;
    
    }
    punchFigs(); 
     message+=pchar;
     }
    
    else{
    if(  pltrue==true)
    {
    message+=ALPHABET_MODE;
    pltrue=false;
    }
     punchLets(); 
     message+=pchar;
      }
     for (int index=0;index <( message.length());index++)
     {
      aChar=message.charAt(index); 
     }
     // myPort.write(aChar);
     print(aChar);
     }
    
     void punchLets()
     {
    
    //println(checkVal);
     switch (vals)
     {
     case 'a':
     pchar=lets[3];
     break;
    
    case 'b':
    pchar=lets[25];
    break;
    
    case 'c':
    pchar=lets[14];
    break;
    
    case 'd':
    pchar=lets[9];
    break;
    
    case 'e':
    pchar=lets[1];
    break;
    
    case 'f':
    pchar=lets[13];
    break;
    
    case 'g':
    pchar=lets[26];
    break;
    
    case 'h':
    pchar=lets[20];
    break;
    
    case 'i':
    pchar=lets[6];
    break;
    
    case 'j':
    pchar=lets[11];
    break;
    
    case 'k':
    pchar=lets[15];
    break;
    
    case 'l':
    pchar=lets[18];
    break;
    
    case 'm':
    pchar=lets[28];
    break;
    
    case 'n':
    pchar=lets[12];
    break;
    
    case 'o':
    pchar=lets[24];
    break;
    
    case 'p':
    pchar=lets[22];
    break;
    
    case 'r':
    pchar=lets[10];
    break;
    
    case 's':
    pchar=lets[5];
    break;
    
    case 't':
    pchar=lets[16];
    break;
    
    case 'u':
    pchar=lets[7];
    break;
    
    case 'v':
    pchar=lets[30];
    break;
    
    case 'w':
    pchar=lets[19];
    break;
    
    case 'x':
    pchar=lets[29];
    break;
    
    case 'y':
    pchar=lets[21];
    break;
    
    case 'z':
    pchar=lets[17];
    break;
    
    case ' ':
    pchar=lets[4];
    break;
    
    case '\n':
    pchar=lets[2];
    break;
    
    case '\r':
    pchar=lets[8];
    break;
    
    
    }
    //  message+=pchar;
    
    }
    
    void punchFigs()
    {
    
    //println(checkVal);
     switch (vals)
     {
      case '-':
      pchar=figs[3];
      break;
    
      case '?':
      pchar=figs[25];
      break;
    
    case ':':
    pchar=figs[14];
    break;
    
    case '\b':
    pchar=figs[9];
    break;
    
    case '3':
    pchar=figs[1];
    break;
    
    case '!':
    pchar=figs[13];
    break;
    
    case '&':
    pchar=figs[26];
    break;
    
    case '$':
    pchar=figs[20];
    break;
    
    case '8':
    pchar=figs[6];
    break;
    
    case '|':
    pchar=figs[11];
    break;
    
    case '(':
    pchar=figs[15];
    break;
    
    case ')':
    pchar=figs[18];
    break;
    
    case '.':
    pchar=figs[28];
    break;
    
    case ',':
    pchar=figs[12];
    break;
    
    case '9':
    pchar=figs[24];
    break;
    
    case '0':
    pchar=figs[22];
    break;
    
    case '4':
    pchar=figs[10];
    break;
    
    case '`':
    pchar=figs[5];
    break;
    
    case '5':
    pchar=figs[16];
    break;
    
    case '7':
    pchar=figs[7];
    break;
    
    case ';':
    pchar=figs[30];
    break;
    
    case '2':
    pchar=figs[19];
    break;
    
    case '/':
    pchar=figs[29];
    break;
    
    case '6':
    pchar=figs[21];
    break;
    
    case '+':
    pchar=figs[17];
    break;
    
    case ' ':
    pchar=figs[4];
    break;
    
    case '\n':
    pchar=figs[2];
    break;
    
    case '\r':
    pchar=figs[8];
    break;
    
    
     }
     //  message+=pchar;
    
     }`
    

    ok I've formatted the whole program with all functions. Maybe now you can make head or tail of it...

  • You are writing your message into your port in keyPressed function. Question 1. Couldn't you just send a String object through your port instead of sending it char by char?

    I implemented changes to your keyPressed function. Instead of writing message to your port, I am writing msgInput, a new String that contains only the input characters plus "27" or "31" according to numeric or string mode features.

    To clarify, when you write 27 (or 31) to your port, do you want to send '2' follow by '7' or you want to send ascii character "27" ?

    Kf

    void keyPressed()
    {
      vals=key;
      String msgInput="";
    
      char aChar=0;
      checkVal=int(vals);
    
      if (checkVal >=33 && checkVal <=63 || checkVal==172)
      {
        if ( pltrue==false)
        {
          msgInput+=NUMBER_MODE;
          pltrue=true;
        }
        punchFigs(); 
        msgInput+=pchar;
      } else {
        if (  pltrue==true)
        {
          msgInput+=ALPHABET_MODE;
          pltrue=false;
        }
        punchLets(); 
        msgInput+=pchar;
      }
    
      message+=msgInput;   
    
      for (int index=0; index <( msgInput.length()); index++)
      {
        aChar=msgInput.charAt(index);
        myPort.write(aChar);
        print(aChar)
      }
    
    }
    
  • Hi.

     > To clarify, when you write 27 (or 31) to your port, do you want to send '2' follow by '7' or you want to send ascii character "27" ?     
    

    If you look at the baudot code table here it might give a bit more of a clue what I'm trying to do...

    cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/colossus/baudot.html

Sign In or Register to comment.