@ -0,0 +1 @@ | |||||
Subproject commit 3bf16f634cdbb2c1fba909a11fff6b7402d5a076 |
@ -0,0 +1,19 @@ | |||||
Copyright (c) 2015 Kevin Nygaard | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in | |||||
all copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE. |
@ -0,0 +1,44 @@ | |||||
# Stentura 200 SRT Controller | |||||
USB controller for Stentura 200 SRT (and similar) stenotype writers using Arduino microprocessor. Allows the Stentura to be used as a realtime-writer via [Plover](http://stenoknight.com/wiki/Main_Page) and a single USB cable. | |||||
## Demo | |||||
- [2015-07-02 Demo](https://youtu.be/ccxri4A-SbM) | |||||
## Configuration | |||||
- Protocol: Gemini PR | |||||
- Baud: 115200 | |||||
- Format: 8-N-1 | |||||
- RTS/CTS: No | |||||
- Xon/Xoff: No | |||||
- Pinout: see source code | |||||
## Doesn't the SRT have a serial port? | |||||
Yes, it does. There are few reasons why I wrote this program: | |||||
1. I didn't have an easily available +12V power supply (it was being used by my router). I didn't want to buy another one without first verifying that the Stentura worked. | |||||
2. The Stentura didn't work when I plugged it in. The lights were on, the processor was responsive, but the serial link wasn't doing anything. | |||||
3. A single +5V USB cable is much cleaner than a +12V power cable and USB-Serial adapter. | |||||
## How it works | |||||
The Stentura consists of three main components: | |||||
1. Mechanicals: the big hunk of metal with gears and springs. This contains the keyboard and all the parts for standalone operation (via paper tape). | |||||
2. IO Expander: sits on top of mechanicals and has the steno alphabet printed on the top. You see it when you open the top cover. | |||||
3. Motherboard: screwed on underneath the mechanicals. Has the power, serial, memory, and processor circuitry. Processor communicates to the IO Expander via a ribbon cable and stores chords into memory. Host requests for chords over serial, which processor handles. | |||||
Something was wrong with the on-board serial, so I decided to bypass the Motherboard entirely. I soldered leads onto the ribbon cable and drove the IO Expander with an Arduino. The Arduino polled the keys and gave them to the host via the Gemini PR protocol, since that was the most straightforward protocol supported by Plover. | |||||
The IO Expander is nothing but a chain of serial shift registers with latches. Each key is weakly pulled up and connected to its own pin on a shift register. When a key is pressed, a little armbar pokes up and shorts the corresponding contact on the IO expander to the case, pulling the signal low. | |||||
To sample the keys, the processor locks/disables the latches on all the shift registers, then clocks out the data. Once done, the latches are reenabled/made transparent to capture the next sample. | |||||
## Improvements | |||||
- Add debounce logic. I haven't really noticed needing this, but it might be necessary when you start to type faster. |
@ -0,0 +1,361 @@ | |||||
/* | |||||
* Evil Copyright (c) 2015 Kevin Nygaard | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
* of this software and associated documentation files (the "Software"), to deal | |||||
* in the Software without restriction, including without limitation the rights | |||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
* copies of the Software, and to permit persons to whom the Software is | |||||
* furnished to do so, subject to the following conditions: | |||||
* | |||||
* The above copyright notice and this permission notice shall be included in | |||||
* all copies or substantial portions of the Software. | |||||
* | |||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
* SOFTWARE. | |||||
*/ | |||||
/* | |||||
* Pinout for Stentura 200 (NOT FOR FLASH) | |||||
* Ribbon | |||||
* |||||| | |||||
* |||||| | |||||
* |||||| | |||||
* xxxxxx (contacts facing up) | |||||
* \\\\\\_ Power +5V | |||||
* \\\\\_ 2 Test | |||||
* \\\\_ 3 Shift load | |||||
* \\\_ 4 Serial out | |||||
* \\_ 5 Clock | |||||
* \_ Ground | |||||
*/ | |||||
/* IO Definitions STENTURA 200*/ | |||||
/* | |||||
#define CLK 5 | |||||
#define DATA_IN 4 | |||||
#define LATCH_EN 3 | |||||
#define TEST_EN 2 | |||||
#define BAUD 115200 | |||||
*/ | |||||
/* | |||||
* Pinout for ProCAT Flash | |||||
* IO Board Pads | |||||
* (NOTE: THIS IS NOT THE RIBBON CABLE, that is different) | |||||
* | |||||
* Pads are in two columns, 1,2,3 and 4,5,6. 1 being the square pad (visible from top). | |||||
* | |||||
* 1 ??? (Must be test. Connects to Resistors) | |||||
* 2 PWR | |||||
* 3 GND | |||||
* | |||||
* 4 Serial Out (Pin 9 of first IC) | |||||
* 5 CLK (Clk rail) | |||||
* 6 SH/LD (Shift Load rail) | |||||
* | |||||
*/ | |||||
/* IO Definitions ProCAT Flash*/ | |||||
#define CLK 5 | |||||
#define DATA_IN 4 | |||||
#define LATCH_EN 6 | |||||
#define TEST_EN 2 //Can't put TEST on 1, which would be UART TX | |||||
#define BAUD 9600 | |||||
#define DEBUG 0 //set to 1 when using Arduino to debug | |||||
#define DEBOUNCE_PERIOD 10 | |||||
#define ARRAY_SIZE(array) \ | |||||
(sizeof(array) / sizeof(*array)) | |||||
/* | |||||
* Setup IO and serial connections | |||||
*/ | |||||
void setup() | |||||
{ | |||||
// Initialize serial | |||||
Serial.begin(BAUD); | |||||
if(DEBUG){ | |||||
Serial.println("Hax Steno Begin"); | |||||
} | |||||
// Setup IOs | |||||
pinMode(CLK, OUTPUT); | |||||
pinMode(LATCH_EN, OUTPUT); | |||||
pinMode(DATA_IN, INPUT); | |||||
//pinMode(TEST_EN, OUTPUT); //Not needed | |||||
// Drive known values to outputs | |||||
digitalWrite(CLK, LOW); | |||||
digitalWrite(LATCH_EN, LOW); | |||||
//digitalWrite(TEST_EN, LOW); //Not needed | |||||
} | |||||
/* | |||||
* Convert raw Stentura byte data into packed Gemini PR format | |||||
* | |||||
* Data that is seemingly skipped is rendundant, and as far as I can tell, | |||||
* unnecessary | |||||
* | |||||
* Raw matrix mapping of Stentura 200 SRT from serial shift registers | |||||
* 0: S- | |||||
* 1: T- | |||||
* 2: K- | |||||
* 3: P- | |||||
* 4: W- | |||||
* 5: H- | |||||
* 6: R- | |||||
* 7: A- | |||||
* 8: O- | |||||
* 9: * | |||||
* 10: -E | |||||
* 11: -U | |||||
* 12: -F | |||||
* 13: -R | |||||
* 14: -P | |||||
* 15: -B | |||||
* 16: -L | |||||
* 17: -G | |||||
* 18: -T | |||||
* 19: -S | |||||
* 20: -D | |||||
* 21: -Z | |||||
* 22: # | |||||
* 23: N/A | |||||
* | |||||
* Gemini PR protocol (from plover source ./plover/machine/geminipr.py) | |||||
* | |||||
* In the Gemini PR protocol, each packet consists of exactly six bytes and the | |||||
* most significant bit (MSB) of every byte is used exclusively to indicate | |||||
* whether that byte is the first byte of the packet (MSB=1) or one of the | |||||
* remaining five bytes of the packet (MSB=0). As such, there are really only | |||||
* seven bits of steno data in each packet byte. This is why the STENO_KEY_CHART | |||||
* below is visually presented as six rows of seven elements instead of six rows | |||||
* of eight elements. | |||||
* STENO_KEY_CHART = ("Fn" , "#" , "#" , "#" , "#" , "#" , "#" , | |||||
* "S-" , "S-", "T-", "K-", "P-", "W-" , "H-" , | |||||
* "R-" , "A-", "O-", "*" , "*" , "res", "res", | |||||
* "pwr", "*" , "*" , "-E", "-U", "-F" , "-R" , | |||||
* "-P" , "-B", "-L", "-G", "-T", "-S" , "-D" , | |||||
* "#" , "#" , "#" , "#" , "#" , "#" , "-Z") | |||||
* | |||||
*/ | |||||
//void construct_data(char raw_data[], char packed_data[]) | |||||
//{ | |||||
// packed_data[0] = 0x80; | |||||
// packed_data[1] = (raw_data[ 0] << 6) /* S- */ | |||||
// | (raw_data[ 1] << 1) /* T- */ | |||||
// | (raw_data[ 2] << 3) /* K- */ | |||||
// | (raw_data[ 3] << 2) /* P- */ | |||||
// | (raw_data[ 4] << 0) /* W- */ | |||||
// | (raw_data[ 5] << 0); /* H- */ | |||||
//packed_data[2] = (raw_data[ 6] << 6) /* R- */ | |||||
// | (raw_data[ 7] << 5) /* A- */ | |||||
// | (raw_data[ 8] << 4) /* O- */ | |||||
// | (raw_data[ 9] << 3); /* * */ | |||||
//packed_data[3] = (raw_data[10] << 3) /* -E */ | |||||
// | (raw_data[11] << 2) /* -U */ | |||||
// | (raw_data[12] << 1) /* -F */ | |||||
// | (raw_data[13] << 0); /* -R */ | |||||
//packed_data[4] = (raw_data[14] << 6) /* -P */ | |||||
// | (raw_data[15] << 5) /* -B */ | |||||
// | (raw_data[16] << 4) /* -L */ | |||||
// | (raw_data[17] << 3) /* -G */ | |||||
// | (raw_data[18] << 2) /* -T */ | |||||
// | (raw_data[19] << 1) /* -S */ | |||||
// | (raw_data[20] << 0); /* -D */ | |||||
//packed_data[5] = (raw_data[22] << 6) /* # */ | |||||
// | (raw_data[21] << 0); /* -Z */ | |||||
//} | |||||
/* ProCAT Flash Mapping | |||||
* | |||||
* The ProCAT Flash is somewhat different. The above Stentura 200 will not work. Instead we have: | |||||
* | |||||
* * Raw matrix mapping of ProCAT Flash from serial shift registers | |||||
* * You can somewhat infer this from the PCB (cheat) by reading letter order, but not all are logical | |||||
* 0: H- // | |||||
* 1: W- // | |||||
* 2: P- // | |||||
* 3: K- // | |||||
* 4: T- //changes marked with comments | |||||
* 5: S- // | |||||
* 6: # // //old was R- | |||||
* | |||||
* 7: A- | |||||
* 8: -R // | |||||
* 9: F // | |||||
* 10: -U // | |||||
* 11: -E // | |||||
* 12: * // | |||||
* 13: -R | |||||
* | |||||
* 14: -P | |||||
* 15: R //was -B | |||||
* 16: -Z // | |||||
* 17: -D // | |||||
* 18: -S // | |||||
* 19: -T // | |||||
* 20: -G // | |||||
* | |||||
* 21: -L ?? | |||||
* 22: # | |||||
* 23: ???? | |||||
* | |||||
* need -B | |||||
*/ | |||||
void construct_data(char raw_data[], char packed_data[]) | |||||
{ | |||||
packed_data[0] = 0x80; | |||||
packed_data[1] = (raw_data[ 5] << 6) /* S- */ //Have to move arrays entries around here, if you are going to | |||||
| (raw_data[ 4] << 4) /* T- */ //change values. Need all 24 bits. | |||||
| (raw_data[ 3] << 3) /* K- */ | |||||
| (raw_data[ 2] << 2) /* P- */ | |||||
| (raw_data[ 1] << 1) /* W- */ | |||||
| (raw_data[ 0] << 0); /* H- */ | |||||
packed_data[2] = (raw_data[ 15] << 6) /* R- */ | |||||
| (raw_data[ 14] << 5) /* A- */ | |||||
| (raw_data[ 13] << 4) /* O- */ | |||||
| (raw_data[ 12] << 3); /* * */ | |||||
packed_data[3] = (raw_data[11] << 3) /* -E */ | |||||
| (raw_data[10] << 2) /* -U */ | |||||
| (raw_data[9] << 1) /* -F */ | |||||
| (raw_data[8] << 0); /* -R */ | |||||
packed_data[4] = (raw_data[23] << 6) /* -P */ // was 14 | |||||
| (raw_data[22] << 5) /* -B */ // was dupe 0 | |||||
| (raw_data[21] << 4) /* -L */ | |||||
| (raw_data[20] << 3) /* -G */ | |||||
| (raw_data[19] << 2) /* -T */ | |||||
| (raw_data[18] << 1) /* -S */ | |||||
| (raw_data[17] << 0); /* -D */ | |||||
packed_data[5] = (raw_data[6] << 6) /* # */ // | |||||
| (raw_data[16] << 0); /* -Z */ | |||||
} | |||||
/* | |||||
* Read keystrokes and return them to the host | |||||
*/ | |||||
void loop(){ | |||||
// Byte array of depressed keys, following mapping above | |||||
// 0 means not pressed, 1 means pressed | |||||
static char pressed_keys[24]; | |||||
// Keys packed in Gemini PR format, ready for transmission over serial | |||||
static char packed_keys[6]; | |||||
// Chord has been started, but is not complete (all keys released) | |||||
static char in_progress; | |||||
// Send data to host over serial | |||||
static char send_data; | |||||
// Debounce counter | |||||
static int debounce_count; | |||||
int i; | |||||
char pressed; | |||||
char keys_down; | |||||
//If keys have already been recorded into pressed_keys array | |||||
if (send_data) { | |||||
construct_data(pressed_keys, packed_keys); | |||||
Serial.write(packed_keys, ARRAY_SIZE(packed_keys)); | |||||
/* | |||||
* Data returned to host, reset stateful variables | |||||
* Note that we don't need to do this in the setup, because they are all | |||||
* static and guaranteed to be 0 by spec | |||||
*/ | |||||
memset(pressed_keys, 0, sizeof(pressed_keys)); | |||||
send_data = 0; | |||||
in_progress = 0; | |||||
// Else, record keys into pressed_keys array | |||||
} else { | |||||
// Latch current state of all keys | |||||
digitalWrite(LATCH_EN, HIGH); | |||||
// Read all latched data | |||||
keys_down = 0; | |||||
for (i = 0; i < ARRAY_SIZE(pressed_keys); i++){ | |||||
/* | |||||
* All inputs are pulled up. Pressing a key shorts the circuit to | |||||
* ground. | |||||
* | |||||
* We invert the logic here to convert to more conventional positive | |||||
* logic. | |||||
*/ | |||||
pressed = !digitalRead(DATA_IN); | |||||
//At this point, you are reading each individual bit in as a 1 if pressed. | |||||
//debug | |||||
if(pressed && DEBUG){ | |||||
Serial.print(pressed, BIN); | |||||
Serial.print("Pressed was high for i = "); | |||||
Serial.println(i); | |||||
} | |||||
// Once a key is pressed, it stays pressed until the chord is over | |||||
// OR result to array | |||||
pressed_keys[i] |= pressed; | |||||
if (pressed) { | |||||
keys_down = 1; | |||||
in_progress = 1; | |||||
} | |||||
/* | |||||
* Toggle clock. Max frequency of shift register MM74HC165 is 30 | |||||
* MHz, so it can be switched without any delay by Arduino. | |||||
*/ | |||||
digitalWrite(CLK, HIGH); | |||||
digitalWrite(CLK, LOW); | |||||
} | |||||
// Make latch transparent again to capture next set of keystrokes | |||||
digitalWrite(LATCH_EN, LOW); | |||||
if (keys_down) { | |||||
debounce_count = 0; | |||||
} | |||||
// Return data to host when all keys have been released | |||||
if (in_progress && !keys_down && (++debounce_count >= DEBOUNCE_PERIOD)) { | |||||
send_data = 1; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,5 @@ | |||||
\relax | |||||
\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}} | |||||
\@writefile{toc}{\contentsline {section}{\numberline {2}Work Log}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Not All ProCAT Flash's will work with Plover}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Reading from a ProCAT Flash with an Arduino}{1}} |
@ -0,0 +1,71 @@ | |||||
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) (preloaded format=pdflatex 2018.11.28) 20 JUN 2019 03:01 | |||||
entering extended mode | |||||
restricted \write18 enabled. | |||||
%&-line parsing enabled. | |||||
**/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs | |||||
/1.tex | |||||
(/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs/ | |||||
1.tex | |||||
LaTeX2e <2014/05/01> | |||||
Babel <3.9l> and hyphenation patterns for 2 languages loaded. | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls | |||||
Document Class: article 2014/09/29 v1.4h Standard LaTeX document class | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo | |||||
File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) | |||||
) | |||||
\c@part=\count79 | |||||
\c@section=\count80 | |||||
\c@subsection=\count81 | |||||
\c@subsubsection=\count82 | |||||
\c@paragraph=\count83 | |||||
\c@subparagraph=\count84 | |||||
\c@figure=\count85 | |||||
\c@table=\count86 | |||||
\abovecaptionskip=\skip41 | |||||
\belowcaptionskip=\skip42 | |||||
\bibindent=\dimen102 | |||||
) (./1.aux) | |||||
\openout1 = `1.aux'. | |||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <12> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <8> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <6> on input line 8. | |||||
[1 | |||||
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./1.aux) ) | |||||
Here is how much of TeX's memory you used: | |||||
230 strings out of 495020 | |||||
2647 string characters out of 6181323 | |||||
48970 words of memory out of 5000000 | |||||
3520 multiletter control sequences out of 15000+600000 | |||||
7887 words of font info for 28 fonts, out of 8000000 for 9000 | |||||
14 hyphenation exceptions out of 8191 | |||||
21i,6n,19p,475b,187s stack positions out of 5000i,500n,10000p,200000b,80000s | |||||
</usr/share/tex | |||||
live/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/share/texlive/t | |||||
exmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texlive/texmf-di | |||||
st/fonts/type1/public/amsfonts/cm/cmr12.pfb></usr/share/texlive/texmf-dist/font | |||||
s/type1/public/amsfonts/cm/cmr17.pfb> | |||||
Output written on 1.pdf (1 page, 54287 bytes). | |||||
PDF statistics: | |||||
24 PDF objects out of 1000 (max. 8388607) | |||||
16 compressed objects within 1 object stream | |||||
0 named destinations out of 1000 (max. 500000) | |||||
1 words of extra memory for PDF output out of 10000 (max. 10000000) | |||||
@ -0,0 +1,22 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{ProCAT Flash and Plover} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
\section{Overview} | |||||
I want to use a ProCAT flash with Plover. | |||||
\section{Work Log} | |||||
\subsection{Not All ProCAT Flash's will work with Plover} | |||||
Some of the plover docs mention that a ProCAT flash will work with a RJ11 to DB9 cable, and that the protocol can be set to Baron. My device must be an older firmware as there is no option to change the protocol, and in fact the RJ11 appears to be only for outbound calling... There is a modem option, and it allows you to call a number. It appears to be for actually calling a phone line. | |||||
Instead, there is an arduino sketch of someone who has previously tapped into the serial out of the IO Expander (essentially the board that reads the keys), and helpfully outlined the process. By cutting the motherboard out of the picture, and driving the IO board directly from a 5V Arduino, one can use the ProCAT without the need for its built in modem. Neat. | |||||
\subsection{Reading from a ProCAT Flash with an Arduino} | |||||
There is a six pin ribbon cable that must be cut in half, and then the arduino connected to it. This is a minimally invasive hack. I can always put the cable back. Let's begin. | |||||
\end{document} |
@ -0,0 +1,15 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{\textbf{The Problem with Hackaday (The problem with Long form reading on websites}} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
The computer screen is not a medium for reading. Its a medium for short paragraphs, videos, and eventually devolves into what social media has become. Whether you like it or not, social media is the epitome of keeping your attention on the computer. Videos, pictures, short text boxes, everything attention grabbing, flashy, musical. What hackaday and other websites, that expect you to read for more than 5-10 seconds need to do, is make a book. The book is the highest medium. Websites are entertainment, advertising, and information. If there was a book that had all articles from the last year, I would be more inclined to read the articles in full. | |||||
\vspace{0.2in} | |||||
As it is, when I find a subject I like on hackaday, i go to the library and get a book on it. Because I can't read on a computer screen. Paper is much better for this purpose. However, it is true, that I could print the webpages out, and that, I am seriously considering. I can't read a computer screen for more than a few minutes. Social media is what the computer is, whether you like it or not. That is apex computer. The pinnacle of computer is social media. Reading is for books, not computers. | |||||
\end{document} |
@ -0,0 +1,8 @@ | |||||
\relax | |||||
\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}} | |||||
\@writefile{toc}{\contentsline {section}{\numberline {2}Work Log}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Not All ProCAT Flash's will work with Plover}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Reading from a ProCAT Flash with an Arduino}{1}} | |||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.1}Never Believe the Internet}{2}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Let's solder new wires on the IO board}{3}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Arduino Sketch}{3}} |
@ -0,0 +1,73 @@ | |||||
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) (preloaded format=pdflatex 2018.11.28) 19 JUN 2019 16:05 | |||||
entering extended mode | |||||
restricted \write18 enabled. | |||||
%&-line parsing enabled. | |||||
**/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs | |||||
/2.tex | |||||
(/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs/ | |||||
2.tex | |||||
LaTeX2e <2014/05/01> | |||||
Babel <3.9l> and hyphenation patterns for 2 languages loaded. | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls | |||||
Document Class: article 2014/09/29 v1.4h Standard LaTeX document class | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo | |||||
File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) | |||||
) | |||||
\c@part=\count79 | |||||
\c@section=\count80 | |||||
\c@subsection=\count81 | |||||
\c@subsubsection=\count82 | |||||
\c@paragraph=\count83 | |||||
\c@subparagraph=\count84 | |||||
\c@figure=\count85 | |||||
\c@table=\count86 | |||||
\abovecaptionskip=\skip41 | |||||
\belowcaptionskip=\skip42 | |||||
\bibindent=\dimen102 | |||||
) (./2.aux) | |||||
\openout1 = `2.aux'. | |||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <12> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <8> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <6> on input line 8. | |||||
[1 | |||||
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] [3] (./2.aux) ) | |||||
Here is how much of TeX's memory you used: | |||||
234 strings out of 495020 | |||||
2695 string characters out of 6181323 | |||||
49970 words of memory out of 5000000 | |||||
3522 multiletter control sequences out of 15000+600000 | |||||
8363 words of font info for 30 fonts, out of 8000000 for 9000 | |||||
14 hyphenation exceptions out of 8191 | |||||
21i,6n,19p,475b,187s stack positions out of 5000i,500n,10000p,200000b,80000s | |||||
</usr/s | |||||
hare/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/share/t | |||||
exlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/share/texlive | |||||
/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texlive/texmf- | |||||
dist/fonts/type1/public/amsfonts/cm/cmr12.pfb></usr/share/texlive/texmf-dist/fo | |||||
nts/type1/public/amsfonts/cm/cmr17.pfb></usr/share/texlive/texmf-dist/fonts/typ | |||||
e1/public/amsfonts/cm/cmtt10.pfb> | |||||
Output written on 2.pdf (3 pages, 90720 bytes). | |||||
PDF statistics: | |||||
38 PDF objects out of 1000 (max. 8388607) | |||||
26 compressed objects within 1 object stream | |||||
0 named destinations out of 1000 (max. 500000) | |||||
1 words of extra memory for PDF output out of 10000 (max. 10000000) | |||||
@ -0,0 +1,82 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{ProCAT Flash and Plover} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
\section{Overview} | |||||
I want to use a ProCAT flash with Plover. | |||||
\section{Work Log} | |||||
\subsection{Not All ProCAT Flash's will work with Plover} | |||||
Some of the plover docs mention that a ProCAT flash will work with a RJ11 to DB9 cable, and that the protocol can be set to Baron. My device must be an older firmware as there is no option to change the protocol, and in fact the RJ11 appears to be only for outbound calling... There is a modem option, and it allows you to call a number. It appears to be for actually calling a phone line. | |||||
Instead, there is an arduino sketch of someone who has previously tapped into the serial out of the IO Expander (essentially the board that reads the keys), and helpfully outlined the process. By cutting the motherboard out of the picture, and driving the IO board directly from a 5V Arduino, one can use the ProCAT without the need for its built in modem. Neat. | |||||
\subsection{Reading from a ProCAT Flash with an Arduino} | |||||
There is a six pin ribbon cable that must be cut in half, and then the arduino connected to it. This is a minimally invasive hack. I can always put the cable back. Let's begin. | |||||
The ink ribbon can be easily removed to gain better access to the IO board. The Shift Registers are TI 74HC165 which means this board may be able to be repaired, if needed. There is a conformal coating on the board, both sides. Funny how laptops don't bother with conformal coatings for waterproofing. | |||||
Vcc is pin 16, and Gnd is 8. Tracing that back to the 6 pin cable to confirm the pinout of the arduino sketch is right, | |||||
\subsubsection{Never Believe the Internet} | |||||
The pinout of the sketch was wrong, for my flash. To be fair, my flash is not a Stentura 200, so that's why. | |||||
My pinout is: | |||||
\begin{verbatim} | |||||
On ribbon cable going from left to right looking from above. | |||||
RIBBON CABLE: | |||||
1 SH/LD (shift) | |||||
2 GND | |||||
3 CLK | |||||
4 PWR | |||||
5 Serial Out | |||||
6 ??? Goes to Resistor | |||||
(INSERT PICTURE) | |||||
On my IO board, the pins are staggered, so there is 1,2,3, | |||||
then another column of 4,5,6 (columns start at the top, | |||||
1 being a square pad). Confusing. | |||||
IO BOARD PADS | |||||
1 ??? Goes to Resistor | |||||
2 PWR | |||||
3 GND | |||||
4 Serial Out | |||||
5 CLK (goes underneath a resistor, then to all clocks) | |||||
6 SH/LD | |||||
(INSERT PICTURE) | |||||
\end{verbatim} | |||||
These pins on the IO board are also soldered to pads (not holes) and fragile. Shit design. Tiny wires. I disconnected one just trying to follow the wires. Also they put some tape w/grease on the wires, and have them in a different order on the PCB from what the ribbon cable wiring is. Shit. Nothing I can't handle, however. | |||||
There are three rails going on the top (bottom?) of the IO board. These are CLOCK, SH/LD, and Power. GND is a copper flood on the top (bottom?) of the IO board. Make sure to double check the pins line up with what you are connecting after building this. | |||||
If you look closely on the circuit board for the IO expander, you might see labels for the Pins. I have G for gnd, + for Pwr, C for clk, etc.. | |||||
\subsection{Let's solder new wires on the IO board} | |||||
I don't need to use the ribbon cable. Instead, let's take off the wires and use my own cable. I still wish the pads were holes, but I'm not making a new PCB for the IO board (though that is feasible). I might however make a PCB to fit inside the Flash... I'll need to edit the Arduino sketch too. | |||||
Not only the IO board, but I'll also need to attach wires to the metal chassis or frame somewhere inside. The Pins of the Steno short the IO expander to ground so I need to have the Arduino connected to chassis as well. | |||||
\subsection{Arduino Sketch} | |||||
I made some edits to the Arduino sketch. One thing noteworthy to myself is the | |||||
\begin{verbatim} | |||||
/* | |||||
* All inputs are pulled up. Pressing a key shorts | |||||
the circuit to | |||||
* ground. | |||||
* | |||||
* We invert the logic here to convert to more | |||||
conventional positive | |||||
* logic. | |||||
*/ | |||||
pressed = !digitalRead(DATA_IN); | |||||
\end{verbatim} | |||||
Haven't see the !variable logic before. Only in booleans, if(!true)... | |||||
\end{document} |
@ -0,0 +1,22 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{ProCAT Flash and Plover} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
\section{Overview} | |||||
I want to use a ProCAT flash with Plover. | |||||
\section{Work Log} | |||||
\subsection{Not All ProCAT Flash's will work with Plover} | |||||
Some of the plover docs mention that a ProCAT flash will work with a RJ11 to DB9 cable, and that the protocol can be set to Baron. My device must be an older firmware as there is no option to change the protocol, and in fact the RJ11 appears to be only for outbound calling... There is a modem option, and it allows you to call a number. It appears to be for actually calling a phone line. | |||||
Instead, there is an arduino sketch of someone who has previously tapped into the serial out of the IO Expander (essentially the board that reads the keys), and helpfully outlined the process. By cutting the motherboard out of the picture, and driving the IO board directly from a 5V Arduino, one can use the ProCAT without the need for its built in modem. Neat. | |||||
\subsection{Reading from a ProCAT Flash with an Arduino} | |||||
There is a six pin ribbon cable that must be cut in half, and then the arduino connected to it. This is a minimally invasive hack. I can always put the cable back. Let's begin. | |||||
\end{document} |
@ -0,0 +1,8 @@ | |||||
\relax | |||||
\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}} | |||||
\@writefile{toc}{\contentsline {section}{\numberline {2}Work Log}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Not All ProCAT Flash's will work with Plover}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Reading from a ProCAT Flash with an Arduino}{1}} | |||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.1}Never Believe the Internet}{2}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Let's solder new wires on the IO board}{3}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Arduino Sketch}{3}} |
@ -0,0 +1,73 @@ | |||||
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) (preloaded format=pdflatex 2018.11.28) 19 JUN 2019 16:32 | |||||
entering extended mode | |||||
restricted \write18 enabled. | |||||
%&-line parsing enabled. | |||||
**/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs | |||||
/3.tex | |||||
(/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs/ | |||||
3.tex | |||||
LaTeX2e <2014/05/01> | |||||
Babel <3.9l> and hyphenation patterns for 2 languages loaded. | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls | |||||
Document Class: article 2014/09/29 v1.4h Standard LaTeX document class | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo | |||||
File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) | |||||
) | |||||
\c@part=\count79 | |||||
\c@section=\count80 | |||||
\c@subsection=\count81 | |||||
\c@subsubsection=\count82 | |||||
\c@paragraph=\count83 | |||||
\c@subparagraph=\count84 | |||||
\c@figure=\count85 | |||||
\c@table=\count86 | |||||
\abovecaptionskip=\skip41 | |||||
\belowcaptionskip=\skip42 | |||||
\bibindent=\dimen102 | |||||
) (./3.aux) | |||||
\openout1 = `3.aux'. | |||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <12> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <8> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <6> on input line 8. | |||||
[1 | |||||
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] [3] (./3.aux) ) | |||||
Here is how much of TeX's memory you used: | |||||
234 strings out of 495020 | |||||
2695 string characters out of 6181323 | |||||
50970 words of memory out of 5000000 | |||||
3522 multiletter control sequences out of 15000+600000 | |||||
8363 words of font info for 30 fonts, out of 8000000 for 9000 | |||||
14 hyphenation exceptions out of 8191 | |||||
21i,6n,19p,475b,187s stack positions out of 5000i,500n,10000p,200000b,80000s | |||||
</usr/s | |||||
hare/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/share/t | |||||
exlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/share/texlive | |||||
/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texlive/texmf- | |||||
dist/fonts/type1/public/amsfonts/cm/cmr12.pfb></usr/share/texlive/texmf-dist/fo | |||||
nts/type1/public/amsfonts/cm/cmr17.pfb></usr/share/texlive/texmf-dist/fonts/typ | |||||
e1/public/amsfonts/cm/cmtt10.pfb> | |||||
Output written on 3.pdf (3 pages, 90854 bytes). | |||||
PDF statistics: | |||||
38 PDF objects out of 1000 (max. 8388607) | |||||
26 compressed objects within 1 object stream | |||||
0 named destinations out of 1000 (max. 500000) | |||||
1 words of extra memory for PDF output out of 10000 (max. 10000000) | |||||
@ -0,0 +1,82 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{ProCAT Flash and Plover} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
\section{Overview} | |||||
I want to use a ProCAT flash with Plover. The ProCAT Flash is a stenography machine. It allows for faster typing, and less strain. Plover is a FOSS Stenography project. | |||||
\section{Work Log} | |||||
\subsection{Not All ProCAT Flash's will work with Plover} | |||||
Some of the plover docs mention that a ProCAT flash will work with a RJ11 to DB9 cable, and that the protocol can be set to Baron. My device must be an older firmware as there is no option to change the protocol, and in fact the RJ11 appears to be only for outbound calling... There is a modem option, and it allows you to call a number. It appears to be for actually calling a phone line. | |||||
Instead, there is an arduino sketch of someone who has previously tapped into the serial out of the IO Expander (essentially the board that reads the keys), and helpfully outlined the process. By cutting the motherboard out of the picture, and driving the IO board directly from a 5V Arduino, one can use the ProCAT without the need for its built in modem. Neat. | |||||
\subsection{Reading from a ProCAT Flash with an Arduino} | |||||
There is a six pin ribbon cable that must be cut in half, and then the arduino connected to it. This is a minimally invasive hack. I can always put the cable back. Let's begin. | |||||
The ink ribbon can be easily removed to gain better access to the IO board. The Shift Registers are TI 74HC165 which means this board may be able to be repaired, if needed. There is a conformal coating on the board, both sides. Funny how laptops don't bother with conformal coatings for waterproofing. | |||||
Vcc is pin 16, and Gnd is 8. Tracing that back to the 6 pin cable to confirm the pinout of the arduino sketch is right, | |||||
\subsubsection{Never Believe the Internet} | |||||
The pinout of the sketch was wrong, for my flash. To be fair, my flash is not a Stentura 200, so that's why. | |||||
My pinout is: | |||||
\begin{verbatim} | |||||
On ribbon cable going from left to right looking from above. | |||||
RIBBON CABLE: | |||||
1 SH/LD (shift) | |||||
2 GND | |||||
3 CLK | |||||
4 PWR | |||||
5 Serial Out | |||||
6 ??? Goes to Resistor | |||||
(INSERT PICTURE) | |||||
On my IO board, the pins are staggered, so there is 1,2,3, | |||||
then another column of 4,5,6 (columns start at the top, | |||||
1 being a square pad). Confusing. | |||||
IO BOARD PADS | |||||
1 ??? Goes to Resistor | |||||
2 PWR | |||||
3 GND | |||||
4 Serial Out | |||||
5 CLK (goes underneath a resistor, then to all clocks) | |||||
6 SH/LD | |||||
(INSERT PICTURE) | |||||
\end{verbatim} | |||||
These pins on the IO board are also soldered to pads (not holes) and fragile. Shit design. Tiny wires. I disconnected one just trying to follow the wires. Also they put some tape w/grease on the wires, and have them in a different order on the PCB from what the ribbon cable wiring is. Shit. Nothing I can't handle, however. | |||||
There are three rails going on the top (bottom?) of the IO board. These are CLOCK, SH/LD, and Power. GND is a copper flood on the top (bottom?) of the IO board. Make sure to double check the pins line up with what you are connecting after building this. | |||||
If you look closely on the circuit board for the IO expander, you might see labels for the Pins. I have G for gnd, + for Pwr, C for clk, etc.. | |||||
\subsection{Let's solder new wires on the IO board} | |||||
I don't need to use the ribbon cable. Instead, let's take off the wires and use my own cable. I still wish the pads were holes, but I'm not making a new PCB for the IO board (though that is feasible). I might however make a PCB to fit inside the Flash... I'll need to edit the Arduino sketch too. | |||||
Not only the IO board, but I'll also need to attach wires to the metal chassis or frame somewhere inside. The Pins of the Steno short the IO expander to ground so I need to have the Arduino connected to chassis as well. | |||||
\subsection{Arduino Sketch} | |||||
I made some edits to the Arduino sketch. One thing noteworthy to myself is the | |||||
\begin{verbatim} | |||||
/* | |||||
* All inputs are pulled up. Pressing a key shorts | |||||
the circuit to | |||||
* ground. | |||||
* | |||||
* We invert the logic here to convert to more | |||||
conventional positive | |||||
* logic. | |||||
*/ | |||||
pressed = !digitalRead(DATA_IN); | |||||
\end{verbatim} | |||||
Haven't see the !variable logic before. Only in booleans, if(!true)... | |||||
\end{document} |
@ -0,0 +1,82 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{ProCAT Flash and Plover} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
\section{Overview} | |||||
I want to use a ProCAT flash with Plover. | |||||
\section{Work Log} | |||||
\subsection{Not All ProCAT Flash's will work with Plover} | |||||
Some of the plover docs mention that a ProCAT flash will work with a RJ11 to DB9 cable, and that the protocol can be set to Baron. My device must be an older firmware as there is no option to change the protocol, and in fact the RJ11 appears to be only for outbound calling... There is a modem option, and it allows you to call a number. It appears to be for actually calling a phone line. | |||||
Instead, there is an arduino sketch of someone who has previously tapped into the serial out of the IO Expander (essentially the board that reads the keys), and helpfully outlined the process. By cutting the motherboard out of the picture, and driving the IO board directly from a 5V Arduino, one can use the ProCAT without the need for its built in modem. Neat. | |||||
\subsection{Reading from a ProCAT Flash with an Arduino} | |||||
There is a six pin ribbon cable that must be cut in half, and then the arduino connected to it. This is a minimally invasive hack. I can always put the cable back. Let's begin. | |||||
The ink ribbon can be easily removed to gain better access to the IO board. The Shift Registers are TI 74HC165 which means this board may be able to be repaired, if needed. There is a conformal coating on the board, both sides. Funny how laptops don't bother with conformal coatings for waterproofing. | |||||
Vcc is pin 16, and Gnd is 8. Tracing that back to the 6 pin cable to confirm the pinout of the arduino sketch is right, | |||||
\subsubsection{Never Believe the Internet} | |||||
The pinout of the sketch was wrong, for my flash. To be fair, my flash is not a Stentura 200, so that's why. | |||||
My pinout is: | |||||
\begin{verbatim} | |||||
On ribbon cable going from left to right looking from above. | |||||
RIBBON CABLE: | |||||
1 SH/LD (shift) | |||||
2 GND | |||||
3 CLK | |||||
4 PWR | |||||
5 Serial Out | |||||
6 ??? Goes to Resistor | |||||
(INSERT PICTURE) | |||||
On my IO board, the pins are staggered, so there is 1,2,3, | |||||
then another column of 4,5,6 (columns start at the top, | |||||
1 being a square pad). Confusing. | |||||
IO BOARD PADS | |||||
1 ??? Goes to Resistor | |||||
2 PWR | |||||
3 GND | |||||
4 Serial Out | |||||
5 CLK (goes underneath a resistor, then to all clocks) | |||||
6 SH/LD | |||||
(INSERT PICTURE) | |||||
\end{verbatim} | |||||
These pins on the IO board are also soldered to pads (not holes) and fragile. Shit design. Tiny wires. I disconnected one just trying to follow the wires. Also they put some tape w/grease on the wires, and have them in a different order on the PCB from what the ribbon cable wiring is. Shit. Nothing I can't handle, however. | |||||
There are three rails going on the top (bottom?) of the IO board. These are CLOCK, SH/LD, and Power. GND is a copper flood on the top (bottom?) of the IO board. Make sure to double check the pins line up with what you are connecting after building this. | |||||
If you look closely on the circuit board for the IO expander, you might see labels for the Pins. I have G for gnd, + for Pwr, C for clk, etc.. | |||||
\subsection{Let's solder new wires on the IO board} | |||||
I don't need to use the ribbon cable. Instead, let's take off the wires and use my own cable. I still wish the pads were holes, but I'm not making a new PCB for the IO board (though that is feasible). I might however make a PCB to fit inside the Flash... I'll need to edit the Arduino sketch too. | |||||
Not only the IO board, but I'll also need to attach wires to the metal chassis or frame somewhere inside. The Pins of the Steno short the IO expander to ground so I need to have the Arduino connected to chassis as well. | |||||
\subsection{Arduino Sketch} | |||||
I made some edits to the Arduino sketch. One thing noteworthy to myself is the | |||||
\begin{verbatim} | |||||
/* | |||||
* All inputs are pulled up. Pressing a key shorts | |||||
the circuit to | |||||
* ground. | |||||
* | |||||
* We invert the logic here to convert to more | |||||
conventional positive | |||||
* logic. | |||||
*/ | |||||
pressed = !digitalRead(DATA_IN); | |||||
\end{verbatim} | |||||
Haven't see the !variable logic before. Only in booleans, if(!true)... | |||||
\end{document} |
@ -0,0 +1,8 @@ | |||||
\relax | |||||
\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}} | |||||
\@writefile{toc}{\contentsline {section}{\numberline {2}Work Log}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Not All ProCAT Flash's will work with Plover}{1}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Reading from a ProCAT Flash with an Arduino}{1}} | |||||
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.1}Never Believe the Internet}{2}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Let's solder new wires on the IO board}{3}} | |||||
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Arduino Sketch}{3}} |
@ -0,0 +1,73 @@ | |||||
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) (preloaded format=pdflatex 2018.11.28) 20 JUN 2019 03:01 | |||||
entering extended mode | |||||
restricted \write18 enabled. | |||||
%&-line parsing enabled. | |||||
**/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs | |||||
/4.tex | |||||
(/home/layoutdev/Desktop/code/documentation_general/Misc_2019/steno_flash/docs/ | |||||
4.tex | |||||
LaTeX2e <2014/05/01> | |||||
Babel <3.9l> and hyphenation patterns for 2 languages loaded. | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls | |||||
Document Class: article 2014/09/29 v1.4h Standard LaTeX document class | |||||
(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo | |||||
File: size11.clo 2014/09/29 v1.4h Standard LaTeX file (size option) | |||||
) | |||||
\c@part=\count79 | |||||
\c@section=\count80 | |||||
\c@subsection=\count81 | |||||
\c@subsubsection=\count82 | |||||
\c@paragraph=\count83 | |||||
\c@subparagraph=\count84 | |||||
\c@figure=\count85 | |||||
\c@table=\count86 | |||||
\abovecaptionskip=\skip41 | |||||
\belowcaptionskip=\skip42 | |||||
\bibindent=\dimen102 | |||||
) (./4.aux) | |||||
\openout1 = `4.aux'. | |||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 6. | |||||
LaTeX Font Info: ... okay on input line 6. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <12> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <8> on input line 8. | |||||
LaTeX Font Info: External font `cmex10' loaded for size | |||||
(Font) <6> on input line 8. | |||||
[1 | |||||
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] [3] (./4.aux) ) | |||||
Here is how much of TeX's memory you used: | |||||
234 strings out of 495020 | |||||
2695 string characters out of 6181323 | |||||
50970 words of memory out of 5000000 | |||||
3522 multiletter control sequences out of 15000+600000 | |||||
8363 words of font info for 30 fonts, out of 8000000 for 9000 | |||||
14 hyphenation exceptions out of 8191 | |||||
21i,6n,19p,475b,187s stack positions out of 5000i,500n,10000p,200000b,80000s | |||||
</usr/s | |||||
hare/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/share/t | |||||
exlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/share/texlive | |||||
/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texlive/texmf- | |||||
dist/fonts/type1/public/amsfonts/cm/cmr12.pfb></usr/share/texlive/texmf-dist/fo | |||||
nts/type1/public/amsfonts/cm/cmr17.pfb></usr/share/texlive/texmf-dist/fonts/typ | |||||
e1/public/amsfonts/cm/cmtt10.pfb> | |||||
Output written on 4.pdf (3 pages, 90854 bytes). | |||||
PDF statistics: | |||||
38 PDF objects out of 1000 (max. 8388607) | |||||
26 compressed objects within 1 object stream | |||||
0 named destinations out of 1000 (max. 500000) | |||||
1 words of extra memory for PDF output out of 10000 (max. 10000000) | |||||
@ -0,0 +1,82 @@ | |||||
\documentclass[11pt]{article} | |||||
%Gummi|065|=) | |||||
\title{ProCAT Flash and Plover} | |||||
\author{Steak Electronics} | |||||
\date{2019} | |||||
\begin{document} | |||||
\maketitle | |||||
\section{Overview} | |||||
I want to use a ProCAT flash with Plover. The ProCAT Flash is a stenography machine. It allows for faster typing, and less strain. Plover is a FOSS Stenography project. | |||||
\section{Work Log} | |||||
\subsection{Not All ProCAT Flash's will work with Plover} | |||||
Some of the plover docs mention that a ProCAT flash will work with a RJ11 to DB9 cable, and that the protocol can be set to Baron. My device must be an older firmware as there is no option to change the protocol, and in fact the RJ11 appears to be only for outbound calling... There is a modem option, and it allows you to call a number. It appears to be for actually calling a phone line. | |||||
Instead, there is an arduino sketch of someone who has previously tapped into the serial out of the IO Expander (essentially the board that reads the keys), and helpfully outlined the process. By cutting the motherboard out of the picture, and driving the IO board directly from a 5V Arduino, one can use the ProCAT without the need for its built in modem. Neat. | |||||
\subsection{Reading from a ProCAT Flash with an Arduino} | |||||
There is a six pin ribbon cable that must be cut in half, and then the arduino connected to it. This is a minimally invasive hack. I can always put the cable back. Let's begin. | |||||
The ink ribbon can be easily removed to gain better access to the IO board. The Shift Registers are TI 74HC165 which means this board may be able to be repaired, if needed. There is a conformal coating on the board, both sides. Funny how laptops don't bother with conformal coatings for waterproofing. | |||||
Vcc is pin 16, and Gnd is 8. Tracing that back to the 6 pin cable to confirm the pinout of the arduino sketch is right, | |||||
\subsubsection{Never Believe the Internet} | |||||
The pinout of the sketch was wrong, for my flash. To be fair, my flash is not a Stentura 200, so that's why. | |||||
My pinout is: | |||||
\begin{verbatim} | |||||
On ribbon cable going from left to right looking from above. | |||||
RIBBON CABLE: | |||||
1 SH/LD (shift) | |||||
2 GND | |||||
3 CLK | |||||
4 PWR | |||||
5 Serial Out | |||||
6 ??? Goes to Resistor | |||||
(INSERT PICTURE) | |||||
On my IO board, the pins are staggered, so there is 1,2,3, | |||||
then another column of 4,5,6 (columns start at the top, | |||||
1 being a square pad). Confusing. | |||||
IO BOARD PADS | |||||
1 ??? Goes to Resistor | |||||
2 PWR | |||||
3 GND | |||||
4 Serial Out | |||||
5 CLK (goes underneath a resistor, then to all clocks) | |||||
6 SH/LD | |||||
(INSERT PICTURE) | |||||
\end{verbatim} | |||||
These pins on the IO board are also soldered to pads (not holes) and fragile. Shit design. Tiny wires. I disconnected one just trying to follow the wires. Also they put some tape w/grease on the wires, and have them in a different order on the PCB from what the ribbon cable wiring is. Shit. Nothing I can't handle, however. | |||||
There are three rails going on the top (bottom?) of the IO board. These are CLOCK, SH/LD, and Power. GND is a copper flood on the top (bottom?) of the IO board. Make sure to double check the pins line up with what you are connecting after building this. | |||||
If you look closely on the circuit board for the IO expander, you might see labels for the Pins. I have G for gnd, + for Pwr, C for clk, etc.. | |||||
\subsection{Let's solder new wires on the IO board} | |||||
I don't need to use the ribbon cable. Instead, let's take off the wires and use my own cable. I still wish the pads were holes, but I'm not making a new PCB for the IO board (though that is feasible). I might however make a PCB to fit inside the Flash... I'll need to edit the Arduino sketch too. | |||||
Not only the IO board, but I'll also need to attach wires to the metal chassis or frame somewhere inside. The Pins of the Steno short the IO expander to ground so I need to have the Arduino connected to chassis as well. | |||||
\subsection{Arduino Sketch} | |||||
I made some edits to the Arduino sketch. One thing noteworthy to myself is the | |||||
\begin{verbatim} | |||||
/* | |||||
* All inputs are pulled up. Pressing a key shorts | |||||
the circuit to | |||||
* ground. | |||||
* | |||||
* We invert the logic here to convert to more | |||||
conventional positive | |||||
* logic. | |||||
*/ | |||||
pressed = !digitalRead(DATA_IN); | |||||
\end{verbatim} | |||||
Haven't see the !variable logic before. Only in booleans, if(!true)... | |||||
\end{document} |
@ -0,0 +1,123 @@ | |||||
//**************************************************************// | |||||
// Name : shiftIn Example 1.1 // | |||||
// Author : Carlyn Maw // | |||||
// Date : 25 Jan, 2007 // | |||||
// Version : 1.0 // | |||||
// Notes : Code for using a CD4021B Shift Register // | |||||
// : // | |||||
//**************************************************************** | |||||
//This tut from arduino | |||||
// doesn't work. | |||||
/* IO Definitions ProCAT Flash*/ | |||||
//#define DATA_IN 4 | |||||
//#define CLK 5 | |||||
//#define LATCH_EN 6 | |||||
//define where your pins are | |||||
int dataPin = 4; | |||||
int clockPin = 5; | |||||
int latchPin = 6; | |||||
//Define variables to hold the data | |||||
//for shift register. | |||||
//starting with a non-zero numbers can help | |||||
//troubleshoot | |||||
byte switchVar1 = 72; //01001000 | |||||
void setup() { | |||||
//start serial | |||||
Serial.begin(9600); | |||||
//define pin modes | |||||
pinMode(latchPin, OUTPUT); | |||||
pinMode(clockPin, OUTPUT); | |||||
pinMode(dataPin, INPUT); | |||||
} | |||||
void loop() { | |||||
//Pulse the latch pin: | |||||
//set it to 1 to collect parallel data | |||||
digitalWrite(latchPin,1); | |||||
//set it to 1 to collect parallel data, wait | |||||
delayMicroseconds(20); | |||||
//set it to 0 to transmit data serially | |||||
digitalWrite(latchPin,0); | |||||
//while the shift register is in serial mode | |||||
//collect each shift register into a byte | |||||
//the register attached to the chip comes in first | |||||
switchVar1 = shiftIn(dataPin, clockPin); | |||||
//Print out the results. | |||||
//leading 0's at the top of the byte | |||||
//(7, 6, 5, etc) will be dropped before | |||||
//the first pin that has a high input | |||||
//reading | |||||
Serial.println(switchVar1, BIN); | |||||
//white space | |||||
Serial.println("-------------------"); | |||||
//delay so all these print satements can keep up. | |||||
delay(500); | |||||
} | |||||
//------------------------------------------------end main loop | |||||
////// ----------------------------------------shiftIn function | |||||
///// just needs the location of the data pin and the clock pin | |||||
///// it returns a byte with each bit in the byte corresponding | |||||
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0 | |||||
byte shiftIn(int myDataPin, int myClockPin) { | |||||
int i; | |||||
double temp = 0; | |||||
int pinState; | |||||
byte myDataIn = 0; | |||||
pinMode(myClockPin, OUTPUT); | |||||
pinMode(myDataPin, INPUT); | |||||
//we will be holding the clock pin high 8 times (0,..,7) at the | |||||
//end of each time through the for loop | |||||
//at the begining of each loop when we set the clock low, it will | |||||
//be doing the necessary low to high drop to cause the shift | |||||
//register's DataPin to change state based on the value | |||||
//of the next bit in its serial information flow. | |||||
//The register transmits the information about the pins from pin 7 to pin 0 | |||||
//so that is why our function counts down | |||||
for (i=7; i>=0; i--) | |||||
{ | |||||
digitalWrite(myClockPin, 0); | |||||
delayMicroseconds(0.2); | |||||
temp = digitalRead(myDataPin); | |||||
if (temp) { | |||||
pinState = 1; | |||||
//set the bit to 0 no matter what | |||||
myDataIn = myDataIn | (1 << i); | |||||
} | |||||
else { | |||||
//turn it off -- only necessary for debuging | |||||
//print statement since myDataIn starts as 0 | |||||
pinState = 0; | |||||
} | |||||
//Debuging print statements | |||||
//Serial.print(pinState); | |||||
//Serial.print(" "); | |||||
//Serial.println (dataIn, BIN); | |||||
digitalWrite(myClockPin, 1); | |||||
} | |||||
//debuging print statements whitespace | |||||
Serial.println(); | |||||
Serial.println(myDataIn, BIN); | |||||
return myDataIn; | |||||
} |
@ -0,0 +1,97 @@ | |||||
//Tut from sparkfun, edited for multiple shift ins. This one works | |||||
//see 74165 data sheets for more details on how it works | |||||
/* IO Definitions ProCAT Flash*/ | |||||
//#define DATA_IN 4 | |||||
//#define CLK 5 | |||||
//#define LATCH_EN 6 | |||||
// HARDWARE CONNECTIONS | |||||
// Connect the following pins between your Arduino and the 74HC165 Breakout Board | |||||
// Connect pins A-H to 5V or GND or switches or whatever | |||||
const int data_pin = 4; // Connect Pin 11 to SER_OUT (serial data out) | |||||
const int clk_pin = 5; // Connect Pin 12 to CLK (the clock that times the shifting) | |||||
const int shld_pin = 6; // Connect Pin 8 to SH/!LD (shift or active low load) | |||||
const int ce_pin = 9; // Connect Pin 9 to !CE (clock enable, active low) | |||||
byte incoming; // Variable to store the 8 values loaded from the shift register | |||||
byte incoming2; // Variable to store the 8 values loaded from the shift register | |||||
byte incoming3; // Variable to store the 8 values loaded from the shift register | |||||
// The part that runs once | |||||
void setup() | |||||
{ | |||||
// Initialize serial to gain the power to obtain relevant information, 9600 baud | |||||
Serial.begin(9600); | |||||
// Initialize each digital pin to either output or input | |||||
// We are commanding the shift register with each pin with the exception of the serial | |||||
// data we get back on the data_pin line. | |||||
pinMode(shld_pin, OUTPUT); | |||||
pinMode(ce_pin, OUTPUT); | |||||
pinMode(clk_pin, OUTPUT); | |||||
pinMode(data_pin, INPUT); | |||||
// Required initial states of these two pins according to the datasheet timing diagram | |||||
digitalWrite(clk_pin, HIGH); | |||||
digitalWrite(shld_pin, HIGH); | |||||
} | |||||
// The part that runs to infinity and beyond | |||||
void loop() { | |||||
incoming = read_shift_regs(); // Read the shift register, it likes that | |||||
// Print out the values being read from the shift register | |||||
Serial.println("\nThe incoming values of the shift register are: "); | |||||
Serial.print("ABCDEFGH : "); | |||||
print_byte(incoming); // Print every 1 and 0 that correlates with A through H | |||||
//Serial.println(incoming,BIN); // This way works too but leaves out the leading zeros | |||||
delay(2000); // Wait for some arbitrary amount of time | |||||
} | |||||
// This code is intended to trigger the shift register to grab values from it's A-H inputs | |||||
byte read_shift_regs() | |||||
{ | |||||
byte the_shifted = 0; // An 8 bit number to carry each bit value of A-H | |||||
// Trigger loading the state of the A-H data lines into the shift register | |||||
digitalWrite(shld_pin, LOW); | |||||
delayMicroseconds(5); // Requires a delay here according to the datasheet timing diagram | |||||
digitalWrite(shld_pin, HIGH); | |||||
delayMicroseconds(5); | |||||
// Required initial states of these two pins according to the datasheet timing diagram | |||||
pinMode(clk_pin, OUTPUT); | |||||
pinMode(data_pin, INPUT); | |||||
digitalWrite(clk_pin, HIGH); | |||||
digitalWrite(ce_pin, LOW); // Enable the clock | |||||
// Get the A-H values | |||||
result1 = shiftIn(data_pin, clk_pin, MSBFIRST); | |||||
result2 = shiftIn(data_pin, clk_pin, MSBFIRST); | |||||
result3 = shiftIn(data_pin, clk_pin, MSBFIRST); | |||||
digitalWrite(ce_pin, HIGH); // Disable the clock | |||||
//return the_shifted; | |||||
} | |||||
// A function that prints all the 1's and 0's of a byte, so 8 bits +or- 2 | |||||
void print_byte(byte val) | |||||
{ | |||||
byte i; | |||||
for(byte i=0; i<=7; i++) | |||||
{ | |||||
Serial.print(val >> i & 1, BIN); // Magic bit shift, if you care look up the <<, >>, and & operators | |||||
} | |||||
Serial.print("\n"); // Go to the next line, do not collect $200 | |||||
} |
@ -0,0 +1,110 @@ | |||||
//Tut from sparkfun, edited for multiple shift ins. This one works. | |||||
//see 74165 data sheets for more details on how it works | |||||
/* IO Definitions ProCAT Flash*/ | |||||
//#define DATA_IN 4 | |||||
//#define CLK 5 | |||||
//#define LATCH_EN 6 | |||||
// HARDWARE CONNECTIONS | |||||
// Connect the following pins between your Arduino and the 74HC165 Breakout Board | |||||
// Connect pins A-H to 5V or GND or switches or whatever | |||||
const int data_pin = 4; // Connect Pin 11 to SER_OUT (serial data out) | |||||
const int clk_pin = 5; // Connect Pin 12 to CLK (the clock that times the shifting) | |||||
const int shld_pin = 6; // Connect Pin 8 to SH/!LD (shift or active low load) | |||||
const int ce_pin = 9; // Connect Pin 9 to !CE (clock enable, active low) | |||||
byte incoming; // Variable to store the 8 values loaded from the shift register | |||||
byte incoming2; // Variable to store the 8 values loaded from the shift register | |||||
byte incoming3; // Variable to store the 8 values loaded from the shift register | |||||
byte results1; | |||||
byte results2; | |||||
byte results3; | |||||
// The part that runs once | |||||
void setup() | |||||
{ | |||||
// Initialize serial to gain the power to obtain relevant information, 9600 baud | |||||
Serial.begin(9600); | |||||
// Initialize each digital pin to either output or input | |||||
// We are commanding the shift register with each pin with the exception of the serial | |||||
// data we get back on the data_pin line. | |||||
pinMode(shld_pin, OUTPUT); | |||||
pinMode(ce_pin, OUTPUT); | |||||
pinMode(clk_pin, OUTPUT); | |||||
pinMode(data_pin, INPUT); | |||||
// Required initial states of these two pins according to the datasheet timing diagram | |||||
digitalWrite(clk_pin, HIGH); | |||||
digitalWrite(shld_pin, HIGH); | |||||
} | |||||
// The part that runs to infinity and beyond | |||||
void loop() { | |||||
read_shift_regs(); // Read the shift register, it likes that | |||||
// Print out the values being read from the shift register | |||||
Serial.println("\nThe incoming values of the shift register are: "); | |||||
Serial.print("ABCDEFGH : "); | |||||
print_byte(results1); // Print every 1 and 0 that correlates with A through H | |||||
//Serial.println(incoming,BIN); // This way works too but leaves out the leading zeros | |||||
Serial.print("IJKLMNOP : "); | |||||
print_byte(results2); | |||||
Serial.print("QRSTUVWX : "); | |||||
print_byte(results3); | |||||
//Serial.println(incoming,BIN); // This way works too but leaves out the leading zeros | |||||
delay(2000); // Wait for some arbitrary amount of time | |||||
} | |||||
// This code is intended to trigger the shift register to grab values from it's A-H inputs | |||||
byte read_shift_regs() | |||||
{ | |||||
byte the_shifted = 0; // An 8 bit number to carry each bit value of A-H | |||||
// Trigger loading the state of the A-H data lines into the shift register | |||||
digitalWrite(shld_pin, LOW); | |||||
delayMicroseconds(5); // Requires a delay here according to the datasheet timing diagram | |||||
digitalWrite(shld_pin, HIGH); | |||||
delayMicroseconds(5); | |||||
// Required initial states of these two pins according to the datasheet timing diagram | |||||
pinMode(clk_pin, OUTPUT); | |||||
pinMode(data_pin, INPUT); | |||||
digitalWrite(clk_pin, HIGH); | |||||
digitalWrite(ce_pin, LOW); // Enable the clock | |||||
// Get the A-H values | |||||
results1 = shiftIn(data_pin, clk_pin, MSBFIRST); | |||||
results2 = shiftIn(data_pin, clk_pin, MSBFIRST); | |||||
results3 = shiftIn(data_pin, clk_pin, MSBFIRST); | |||||
digitalWrite(ce_pin, HIGH); // Disable the clock | |||||
//return the_shifted; | |||||
} | |||||
// A function that prints all the 1's and 0's of a byte, so 8 bits +or- 2 | |||||
void print_byte(byte val) | |||||
{ | |||||
byte i; | |||||
for(byte i=0; i<=7; i++) | |||||
{ | |||||
Serial.print(val >> i & 1, BIN); // Magic bit shift, if you care look up the <<, >>, and & operators | |||||
} | |||||
Serial.print("\n"); // Go to the next line, do not collect $200 | |||||
} |