#include "Arduino.h" bool use_rn=false; //if use_rn=true, CR and LF only do what they say. if use_rn=false \r is ignored and \n does CRLF(=Enter) //Arduino 1.8.3 //STM32F103C, 64k flash //upload method: serial (A9 to RX, A10 to TX) //To upload set Boot0 jumper to 1 (the one further away from reset btn) and press reset (stm will boot from flash wich contains uart to flash uploader) //To boot program after restart set Boot0 jumper to 0 //#define DEBUG #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) void checkSerial(); bool textAvailable(); bool checkTextbuffer(); void sendChar(char c,char c2); void coilInterrupt(); //pins die nicht gehn als output: /* PA15 * PB3 * PB4 * PA12 */ #if defined(BROTHERAX240) #define SCAN_0 PA1 #define SCAN_1 PA2 #define SCAN_2 PA3 #define SCAN_3 PA4 #define SCAN_4 PA5 #define SCAN_5 PA6 #define SCAN_6 PA7 #define SCAN_7 PB0 #define SCAN_8 PB1 #define IN_A PB13 #define IN_B PB14 #define IN_C PB15 #define IN_D PB5 #define IN_E PB6 #define IN_F PB7 #define IN_G PB8 #define IN_H PB9 #elif defined(BROTHERAX130) #define SCAN_0 PA1 #define SCAN_1 PA2 #define SCAN_2 PA3 #define SCAN_3 PA4 #define SCAN_4 PA5 #define SCAN_5 PA6 #define SCAN_6 PA7 #define SCAN_7 PB0 //#define SCAN_8 PB1 #define IN_A PB13 #define IN_B PB14 #define IN_C PB15 #define IN_D PB5 #define IN_E PB6 #define IN_F PB7 #define IN_G PB8 #define IN_H PB9 #endif #define PIN_LED PC13 #if !defined(PIN_COIL_SENSE) #define PIN_COIL_SENSE PB11 #endif #define LEDON LOW #define LEDOFF HIGH #if defined(BROTHERAX240) #define NUM_SCANPINS 9 int scanaddress[]={SCAN_0,SCAN_1,SCAN_2,SCAN_3,SCAN_4,SCAN_5,SCAN_6,SCAN_7,SCAN_8}; #define NUM_INADDR 8 int inaddress[]={IN_A,IN_B,IN_C,IN_D,IN_E,IN_F,IN_G,IN_H}; #include "matrix_ax240.h" #elif defined(BROTHERAX130) #define NUM_SCANPINS 8 int scanaddress[]={SCAN_0,SCAN_1,SCAN_2,SCAN_3,SCAN_4,SCAN_5,SCAN_6,SCAN_7}; #define NUM_INADDR 8 int inaddress[]={IN_A,IN_B,IN_C,IN_D,IN_E,IN_F,IN_G,IN_H}; #include "matrix_ax130.h" #endif #define TEXTBUFFERSIZE 8192 byte textbuffer[TEXTBUFFERSIZE]; //ca 60-65 Zeilen pro DinA4, a 65 characters (10 Pica), 78 characters (12 Elite) or 97 characters (15 Mikron) uint16_t bufferpos_write=0; uint16_t bufferpos_read=0; #define DELAY_KEYPRESS 100 //delay in ms between keypresses long last_keypress=0; bool linefeed_used=false; //if Linefeed key was used CR (CODE+Enter) must be pressed twice for full CR volatile uint16_t count_bufferedchars=0; //keeps track of buffered characters on the typewriter #define MAX_TYPEWRITER_BUFFERCOUNT 2 #define MAXIMUM_COILWAIT 5000 //if no interrupt from coil received decrease buffer count after this time (in ms) void setup() { if (use_rn) { //change matrix mapping if CR and LF are used #if defined(BROTHERAX240) byte _km10[NUM_SCANPINS]={0,0,16,0,0,0,0,0,0}; //10 = [LINE FEED] byte _km13[NUM_SCANPINS]={0,36,0,0,0,0,0,0,0}; //13 = [CARRIAGE RETURN] #elif defined(BROTHERAX130) byte _km10[NUM_SCANPINS]={0,64,0,0,0,0,0,0}; //10 = [LINE FEED] byte _km13[NUM_SCANPINS]={0,0,0,0,0,0,0,0}; //13 = [CARRIAGE RETURN] #endif for (uint8_t i=0;ilast_keypress+DELAY_KEYPRESS){ if (count_bufferedchars0 && millis()>last_keypress+MAXIMUM_COILWAIT){ //coil response timeout count_bufferedchars--; //decrease buffer count last_keypress=millis(); } } if (count_bufferedchars>=MAX_TYPEWRITER_BUFFERCOUNT){ digitalWrite(PIN_LED,LEDON); //led on -> wait for buffer to empty }else{ digitalWrite(PIN_LED,LEDOFF); //led off -> buffer isnt full } } void checkSerial(){ while(Serial1.available()){ if (Serial1.available()>0){ char c=Serial1.read(); bufferpos_write++; bufferpos_write%=TEXTBUFFERSIZE; textbuffer[bufferpos_write]=c; //bufferpos_write points to last written char position if (use_rn) { if (c==10 || (c==13 && linefeed_used)) { //char 10 is LineFeed. If emulated by pressing 2,4 (arrow down, top right of keyboard), key needs to be pressed twice to get one line spacing //Also CR (CODE+Enter) must be pressed twice, if LineFeed key is used in the same Text Line bufferpos_write++; bufferpos_write%=TEXTBUFFERSIZE; textbuffer[bufferpos_write]=c; //bufferpos_write points to last written char position } if (c==13) { linefeed_used=false; }else if(c==10){ linefeed_used=true; } } } } } bool textAvailable(){ if (bufferpos_write!=bufferpos_read){ return true; } return false; } bool checkTextbuffer(){ bool returnvalue=false; //while(Serial1.available()){ //if (Serial1.available()>0){ if (textAvailable()) { //buffer contains unread chars bufferpos_read++;//bufferpos_read points to last read char position bufferpos_read%=TEXTBUFFERSIZE; char c = textbuffer[bufferpos_read]; #ifdef DEBUG Serial1.print((uint8_t)c); //echo Serial1.print("="); //echo Serial1.println(c); //echo #endif if (c==195 || c==194) { //umlaut #ifdef DEBUG Serial1.print("Uml:"); #endif while (!textAvailable()){ checkSerial(); } //wait for next byte and checkSerial in between bufferpos_read++;//bufferpos_read points to last read char position bufferpos_read%=TEXTBUFFERSIZE; char c2=textbuffer[bufferpos_read]; #ifdef DEBUG Serial1.println((uint8_t)c2); //echo #endif sendChar(c,c2); //2 byte character returnvalue=true; }else{ sendChar(c,0); //normal 1 byte character returnvalue=true; } } //} return returnvalue; //true= character send, false=buffer was empty } void sendChar(char c,char c2) { //c2 =0 for 1 byte characters uint8_t keypress[NUM_SCANPINS]={0}; //keypress contains id of input pin. 0=not pressed, A=2^0, B=2^1, C=2^3 ... //check if key is implemented (not all 255,255,255,..) bool keyimplemented=false; for (uint8_t i=0;i=32 && c<127) || c==10 || c==13 ) ) { //1 byte char #ifdef DEBUG Serial1.println("1 byte char"); #endif for (uint8_t i=0;i=32){ //not recognized character (everything else) and not a control command keypress[1]=128; // [SPACE] //print space to keep text aligned } //Update count buffered chars if ((c>32 && c<127) ) { //pressed key uses hammer. (32 is space) if (keyimplemented){ //keymatrix was implemented for c (not 255,255...) count_bufferedchars++; //character send to typewriter. Increase character buffer count } } //digitalWrite(PIN_LED,LEDON); #define HOLDCYCLES 3 for (uint8_t hold=0;hold transistor pulls input of printer to ground } } } } } //digitalWrite(PIN_LED,LEDOFF); } void coilInterrupt(){ if (count_bufferedchars>0){ count_bufferedchars--; } }