`LTV-1200 --RS232-> Raspberry Pi Serialport --> Local Node.JS Bridge --WebSocket-> Browser Display`
Data streams 'realtime' packets from the LTV at ~ 10ms intervals (+ / - 5ms) (per the datasheet), but I observed some occasional drop-outs: I think these happen when the vent sends some other packet type (alarms).
Otherwise, data is cached locally on the raspberry pi, and clients can request it in intervals: sending with their query the time-stamp of their most-recent slice: the pi should respond as best it can with a full update since then.
Qualitative MVP video below, next steps probably:
- pretty-ify,
- run for ~ hours, verify no memory leaks etc
- do on RPI4, see if HZ can improve
- circuit for RS232 interface, RPI screen mount
- UI for system reset / reboot,
- UI for system state (vent connection OK? ws connection OK?)
- label flows
Agree no need for oxygen, the ventilator will run from the internal turbine
Horizontal access should be time - 3-6 seconds.
Tidal volume is always positive so 0-1000 ml would cover all contingencies.
Pressure also typically positive os scale is 0 - 80 should cover every possibility - most patients are ventilated at less than 45 cm H2O.
- get the lung
- write the UI, make the circuit
## Log
## 2021 01 01
Drawing the circuit today.
| Part | PN |
| --- | --- |
| Tranciever, RS232 | 296-9598-1-ND / MAX3238C |
| RJ12 Jack | WM5567CT-ND |
| 40 Pin RPI Female Header | S6104-ND |
The way I have this set up, I mostly just have a small height issue.
OK, this is pretty simple.


## 2020 11 18

In order of appearance, this video should be:
- 'prox pressure'
- 'xdcr flow'
- volume
## 2020 11 05
### Yonder Phy
We have an RJ45 port, pinouts are
| pin | sig |
| --- | --- |
| 1 | SGND |
| 2 | TxD |
| 3 | RxD |
| 4 | CTS |
| 5 | RTS |
| 6 | SGND |
Seems like this should be straightforward - datasheet notes that data is uni-directional, my guess is that it just spews data out of the port, wouldn't that be nice.
First move is to get it venting. [Setup Guide](https://bu.digication.com/bumc-ed1/ltv-ventilator-setup-and-initial-settings)
OK, have woken it up with a glove, can confirm it has an RS232 out that just spews data - that's great. I do need an RS232 interface though, which swings -10 to +10v here.
OK, turned the vent on today, and got characters from the RS232 port. Have an RPI setup and ready to test with some code tomorrow morning, and a temporary RS232-TTL adapter to splice in between. Some concern about the RPI's serial port being 'in use' when bluetooth module is being used, etc. RPI 4 has mucho ++ serial ports, will try to use one of those in the end run.
So, first move tomorrow is getting the serial port hooked up & seeing if I can pull anything into JS, then is a little software architecting.
## 2020 11 06
Serial on the RPI3 is a pain, have to disable a bunch of things:
- used node serialport (not the particular raspi-serial library)
- set it up for /dev/ttyAMA0, the default port
- baudrate to 60096
- use a bytelength parser
- disable the uart terminal / enable the uart hardware in `sudo raspi-config`
- put `dtoverlay=pi3-disable-bt` in `/boot/config.txt`
- did `sudo systemctl disable hciuart`
- rebooted
- now I am recieving bytes
So I should decode some packets.
Packets: decoded. Now I want the 'other end' of it, my bootstrap code / server / client.
Cool, have a bootstrap up, just need to plug it into the ltv, get three plots up and one state-swapping thing, then it should be ahn MVP, next step would be a circuit / display.
OK, I have the client / server architecture setup now... so just one more day at that and I should have an MVP, good enough to proceed with a circuit etc.
\ No newline at end of file
## LTV 1200 Ventilator Display
The LTV-1200 is an (ageing) ventilator, unpopular in practice due to its lack of display.
Luckily, the thing has an RS232 port which streams data in roughly 10ms intervals
We were able to read packets off of this line using a [Raspberry Pi](https://www.raspberrypi.org/), [node.js](https://nodejs.org/en/) and a small RS232 tranciever circuit from [pololu](https://www.pololu.com/product/126).

### How it Works
The LTV's [serial protocol is well documented by the OEM](11024-J_LTV-LTM_Serial_Communication_Protocol_For_Customers.pdf):
| - | type | electrical | baud rate | data bits | parity | stop bits |
| --- | --- | --- | --- | --- | --- | --- |
| spec | uart | R232 | 60096 | 8 | none | 2 |
| permitted | " | " | 57600 | 8 | none | 1 |
The LTV will spew "real time" packets from the RS232 port on a regular 10ms interval, *even if you donot ask anything of it* - this just happens all the time. This means code does not have to handshake with the device, there is no state in the connection, etc. Data emerges. This is the way.
Packets are simple as well, delineating them is easiest to document with this code snippet (but is also well documented in their serial protocol doc linked above). Structure is like:
| b0 | b1 | b2 | b3:n | bn |
| --- | --- | --- | --- | --- |
| start = 255 | length | packet type | data | CRC |
```javascript
letpacket=newUint8Array(255)
letpi=0// packet indice (where inside of, during parse)
letpl=0// packet length (expected len)
letip=false// in packet (delineation state)
parser.on('data',(data)=>{
// read if
if(ip){
if(pi==0){
// length byte
pl=data[0]
}
// store all bytes, increment ptr
packet[pi]=data[0]
pi++
if(pi>pl+1){
onPacket(packet)// pass, then ptr swap to new... shouldn't leak back
packet=newUint8Array(255)
pi=0
pl=0
ip=false
}
}
// start byte / 0xFA
if(data[0]==250&&!ip){
ip=true
pi=0
}
})
```
I only ever read "real time" packets from the device, using this structure:
```javascript
// switch on the packet type:
switch(pck[1]){
case1:
//realtime data
//[2] uint8 insp state (table of 18 states)
//[3,4] int16 prox pres (-5 to 120)
//[5,6] int16 xdcr flow (-200 to 200)
//[7,8] int16 volume (1ml res) (0 to 3000)
letdata={
inspState:TS.read('uint8',pck,2),
proxPres:TS.read('int16',pck,3),
xdcrFlow:TS.read('int16',pck,5),
volume:TS.read('int16',pck,7)
}
// seems like this works, I guess timestamp these things now and keep them around locally...
// then run a server, client should req. the local store ?
The Raspberry Pi has a hardware serial port, and runs linux. This means we can write our code in javascript (making it easy to update / modify / distribute) while still operating otherwise PITA serialports. Also, javascript is a wonderful language to write servers and clients in.
The serialport needs an RS232 interface, I have also drawn this circuit to connect the raspberry pi's TTL UART to the RS232 connection on the vent:

The circuit is available in the repository, designed in eagle [here](circuit).
### Server / Client Architecture
To make the web app, I launch [ltv.js](code/ltv.js) on the Raspberry Pi which is connected to the LTV. Configuring the Raspberry Pi's serialport can be somewhat cumbersome, I have notes on that in [the log](log/log.md).
This initalizes a server on the raspberry pi, and announces its availability on the raspberry pi's terminal. The IP address and port presented can be navigated to with any browser (or phone) and the following will happen:
- the client will request index.html,
- the client will load the script referenced in index.html,
-*this script* will request that the server start a sub-process: `code/local/ltv-bridge.js`
- the `ltv-bridge.js` process connects to the ltv via the serialport, and to the client via a websocket
- websocket coordinates are delivered to the client automatically by `ltv.js`
- when the `ltv-bridge` delineates a "realtime" packet on the serialport, it will button this up into a javascript object and whip it across the websocket to the client
- the client will add this data to a series of plots in the UI and redraw them
### What is Not Done
We have not tested this for long durations.
The UI is a scratchpad, and could use work. Recommended settings for the UI were:
- Horizontal access should be time - 3-6 seconds (width of X axis in plots)
- Tidal volume is always positive so 0-1000 ml would cover all contingencies.
`LTV-1200 --RS232-> Raspberry Pi Serialport --> Local Node.JS Bridge --WebSocket-> Browser Display`
Data streams 'realtime' packets from the LTV at ~ 10ms intervals (+ / - 5ms) (per the datasheet), but I observed some occasional drop-outs: I think these happen when the vent sends some other packet type (alarms).
Otherwise, data is cached locally on the raspberry pi, and clients can request it in intervals: sending with their query the time-stamp of their most-recent slice: the pi should respond as best it can with a full update since then.
Qualitative MVP video below, next steps probably:
- pretty-ify,
- run for ~ hours, verify no memory leaks etc
- do on RPI4, see if HZ can improve
- circuit for RS232 interface, RPI screen mount
- UI for system reset / reboot,
- UI for system state (vent connection OK? ws connection OK?)
- label flows
Agree no need for oxygen, the ventilator will run from the internal turbine
Horizontal access should be time - 3-6 seconds.
Tidal volume is always positive so 0-1000 ml would cover all contingencies.
Pressure also typically positive os scale is 0 - 80 should cover every possibility - most patients are ventilated at less than 45 cm H2O.
- get the lung
- write the UI, make the circuit
## Log
## 2021 01 01
Drawing the circuit today.
| Part | PN |
| --- | --- |
| Tranciever, RS232 | 296-9598-1-ND / MAX3238C |
| RJ12 Jack | WM5567CT-ND |
| 40 Pin RPI Female Header | S6104-ND |
The way I have this set up, I mostly just have a small height issue.
OK, this is pretty simple.


## 2020 11 18

In order of appearance, this video should be:
- 'prox pressure'
- 'xdcr flow'
- volume
## 2020 11 05
### Yonder Phy
We have an RJ45 port, pinouts are
| pin | sig |
| --- | --- |
| 1 | SGND |
| 2 | TxD |
| 3 | RxD |
| 4 | CTS |
| 5 | RTS |
| 6 | SGND |
Seems like this should be straightforward - datasheet notes that data is uni-directional, my guess is that it just spews data out of the port, wouldn't that be nice.
First move is to get it venting. [Setup Guide](https://bu.digication.com/bumc-ed1/ltv-ventilator-setup-and-initial-settings)
OK, have woken it up with a glove, can confirm it has an RS232 out that just spews data - that's great. I do need an RS232 interface though, which swings -10 to +10v here.
OK, turned the vent on today, and got characters from the RS232 port. Have an RPI setup and ready to test with some code tomorrow morning, and a temporary RS232-TTL adapter to splice in between. Some concern about the RPI's serial port being 'in use' when bluetooth module is being used, etc. RPI 4 has mucho ++ serial ports, will try to use one of those in the end run.
So, first move tomorrow is getting the serial port hooked up & seeing if I can pull anything into JS, then is a little software architecting.
## 2020 11 06
Serial on the RPI3 is a pain, have to disable a bunch of things:
- used node serialport (not the particular raspi-serial library)
- set it up for /dev/ttyAMA0, the default port
- baudrate to 60096
- use a bytelength parser
- disable the uart terminal / enable the uart hardware in `sudo raspi-config`
- put `dtoverlay=pi3-disable-bt` in `/boot/config.txt`
- did `sudo systemctl disable hciuart`
- rebooted
- now I am recieving bytes
So I should decode some packets.
Packets: decoded. Now I want the 'other end' of it, my bootstrap code / server / client.
Cool, have a bootstrap up, just need to plug it into the ltv, get three plots up and one state-swapping thing, then it should be ahn MVP, next step would be a circuit / display.
OK, I have the client / server architecture setup now... so just one more day at that and I should have an MVP, good enough to proceed with a circuit etc.