Skip to content

Commit

Permalink
Merge pull request #261 from RobertGawron/feature/rev_5_0
Browse files Browse the repository at this point in the history
Feature/rev 5 0
  • Loading branch information
RobertGawron authored Aug 7, 2021
2 parents 1d374f2 + 50cfdd0 commit f562f85
Show file tree
Hide file tree
Showing 17 changed files with 385 additions and 208 deletions.
Binary file modified Documentation/Diagrams/UARTFrameFormat-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
221 changes: 124 additions & 97 deletions Documentation/Diagrams/UARTFrameFormat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 7 additions & 6 deletions Documentation/Diagrams/UARTFrameFormat.tex
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,21 @@


\node (StartPoint) [text depth=13pt, text height=6pt]{};
\shnode{StartPoint}{MsgId}{msg id};
\shnode{MsgId}{MsgLen}{msg length};
\lnode{MsgLen}{Configuration}{ADC configuration};
\shnode{StartPoint}{MsgType}{msg type};
\shnode{MsgType}{MsgLen}{msg length};
\lnode{MsgLen}{MsgCounter}{msg \\ counter};
\lnode{MsgCounter}{Configuration}{ADC configuration};
\lnode{Configuration}{MSBADC}{MSB ADC value};
\lnode{MSBADC}{LSBADC}{LSB ADC value};
\lnode{LSBADC}{CRC}{CRC};

\draw[decorate,decoration={brace,raise=3pt}] (MsgId.north west) -- node[above=4pt] {Preamble} (MsgLen.north east);
\draw[decorate,decoration={brace,raise=3pt}] (MsgType.north west) -- node[above=4pt] {Preamble} (MsgCounter.north east);
\draw[decorate,decoration={brace,raise=3pt}] (Configuration.north west) -- node[above=4pt] {Data} (LSBADC.north east);
\draw[decorate,decoration={brace,raise=3pt}] (CRC.north west) -- node[above=4pt] {CRC} (CRC.north east);

\draw (MsgId.south west) -- +(0,-1.2cm);
\draw (MsgType.south west) -- +(0,-1.2cm);
\draw (MsgLen.south east) -- +(0,-1.2cm);
\draw[<->] ( $ (MsgId.south west) +(0,-0.6cm) $ ) -- node[fill=white] {1 Byte} ( $ (MsgLen.south east) +(0,-0.6cm) $ );
\draw[<->] ( $ (MsgType.south west) +(0,-0.6cm) $ ) -- node[fill=white] {1 byte} ( $ (MsgLen.south east) +(0,-0.6cm) $ );


\end{tikzpicture}
Expand Down
11 changes: 0 additions & 11 deletions Simulation/hardware_connection.py

This file was deleted.

6 changes: 3 additions & 3 deletions Simulation/main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import sys
sys.path.append('../Software/DataAcquisition')

from hardware_connection import HardwareConnection # noqa: E402
from physical_layer import PhysicalLayer # noqa: E402
from state_machine import IonizationChamberStateMachine # noqa: E402
import config # noqa: E402

if __name__ == "__main__":
hardware = HardwareConnection(config)
machine = IonizationChamberStateMachine(hardware)
physicalLayer = PhysicalLayer(config)
machine = IonizationChamberStateMachine(physicalLayer)

while True:
machine.tick()
11 changes: 11 additions & 0 deletions Simulation/physical_layer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@


class PhysicalLayer:
def __init__(self, config):
pass

def connect(self):
pass

def getData(self):
return [1, 2, 3, 4, 5, 9]
52 changes: 41 additions & 11 deletions Software/DataAcquisition/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,61 @@
# Firmware
## Setting up development environment on Linux


## Setup
1. Install tools via apt-get:

* [Setting up development environment on Linux
](https://github.com/RobertGawron/IonizationChamber/wiki/Setting-up-development-environment-on-Linux)
```console
apt-get install screen git sdcc doxygen uncrustify libusb-1.0-0-dev python3-pip texlive-latex-base texlive-latex-extra texlive-extra-utils poppler-utils cmake cppcheck r-base-core shellcheck
```

3. Install python libraries.
```console
pip3 install pyserial
pip3 install flake8 flake8-html
```

## Architecture
4. Install R libraries, run R in command line:
```console
pi@raspberrypi:~/IonizationChamber/software/DataAcquisitionFromDevice $ R

R version 3.5.2 (2018-12-20) -- "Eggshell Igloo"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: arm-unknown-linux-gnueabihf (32-bit)
```

Type (write yes on next prompts):

```
install.packages('latticeExtra')
```

```
install.packages('gridExtra')
```

```
install.packages('Hmisc')
```

<img src="../../Documentation/Diagrams/HostArchitecture.svg" width="100%">

## Collecting measurements

1. **Edit config.py** to select the correct COM port of Ionization Chamber. Note that **useDMM flag should be set to False**, is experimental and was supposed to be used to check the correlation of Ionization Chamber with other factors (measured by DMM with SCPI support), such factors could be e.g. temperature.

2. **Run data acquisition script**, it will log Ionization Chamber output on the screen and also it will save it to data.csv for further processing.

```python main.py```

3. When all data is logged, terminate ```python main.py``.
```
python main.py
```

## Plotting signal value in domain time + plotting histogram

This mode is useful to look on measurement changes over time.

After collecting data run script to post-process it and generate diagrams:

```Rscript main.R```
```
Rscript main.R
```

A new .png image with timestamp in its name will be created in directory where script is.

Expand All @@ -42,7 +70,9 @@ Below is example of such generated plot.
2. Edit ```boxplot.R```, to match filenames of .cvs files and labels of measurements.
3. Run:

```Rscript boxplot.R```
```
Rscript boxplot.R
```

A new .png image with timestamp in its name will be created in directory where script is.

Expand Down
45 changes: 45 additions & 0 deletions Software/DataAcquisition/application_layer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from transport_layer import TransportLayer
from enum import Enum


class ADC_RESOLUTION(Enum):
R12 = 1
R13 = 2
R14 = 3


def convert(upperByte, lowerByte, resolution):
"""
based on https://ww1.microchip.com/downloads/en/DeviceDoc/22072b.pdf
assumed that gain = 1
"""
def digitalToAnalog(value, lsb, pga):
return (value * (lsb / pga))

digitalOutput = (upperByte << 8) | lowerByte

if resolution == ADC_RESOLUTION.R12:
return digitalToAnalog(digitalOutput, (1 * 0.01), 1)

if resolution == ADC_RESOLUTION.R13:
return digitalToAnalog(digitalOutput, (250 * 0.0000001), 1)

if resolution == ADC_RESOLUTION.R14:
return digitalToAnalog(digitalOutput, (62.5 * 0.000001), 1)


class ApplicationLayer:
def __init__(self, physicalLayer):
self.transportLayer = TransportLayer(physicalLayer)

def connect(self):
self.transportLayer.connect()

def getMeasurement(self):
dataIn = self.transportLayer.getFrame()

(msb, lsb) = (dataIn[2], dataIn[3])
deviceMeasurement = convert(
msb, lsb, ADC_RESOLUTION.R14)

return deviceMeasurement
19 changes: 0 additions & 19 deletions Software/DataAcquisition/ionization_chamber.py

This file was deleted.

6 changes: 3 additions & 3 deletions Software/DataAcquisition/main.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

from hardware_connection import HardwareConnection
from physical_layer import PhysicalLayer
from state_machine import IonizationChamberStateMachine
import config

if __name__ == "__main__":
hardware = HardwareConnection(config)
machine = IonizationChamberStateMachine(hardware)
physicalLayer = PhysicalLayer(config)
machine = IonizationChamberStateMachine(physicalLayer)

while True:
machine.tick()
27 changes: 0 additions & 27 deletions Software/DataAcquisition/mcp3425.py

This file was deleted.

15 changes: 15 additions & 0 deletions Software/DataAcquisition/measurement_storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import csv


class MeasurementStorage:
def __init__(self):
self.CVS_FileName = "data.csv"
self.CVS_Header = ['Time', 'Counter']

def connect(self):
CVS_Handler = open(self.CVS_FileName, 'w', encoding='UTF8', newline='')
self.CVS_Writter = csv.writer(CVS_Handler)
self.CVS_Writter.writerow(self.CVS_Header)

def saveMeasurement(self, date, measurement):
self.CVS_Writter.writerow([date, measurement])
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from serial import Serial


class HardwareConnection:
class PhysicalLayer:
def __init__(self, config):
self.config = config

Expand All @@ -14,6 +14,7 @@ def connect(self):
self.serialPort.isOpen()
self.serialPort.flushInput()

def getMeasurement(self):
dataIn = self.serialPort.read(5)
def getData(self):
msgLength = 6
dataIn = self.serialPort.read(msgLength)
return dataIn
31 changes: 16 additions & 15 deletions Software/DataAcquisition/state_machine.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,40 @@
import datetime
from ionization_chamber import IonizationChamber
from application_layer import ApplicationLayer
from measurement_storage import MeasurementStorage


class IonizationChamberStateMachine:
def __init__(self, hardware):
self.hardware = hardware
def __init__(self, physicalLayer):
self.applicationLayer = ApplicationLayer(physicalLayer)
self.deviceMeasurement = 0.0
self.measurementStorage = MeasurementStorage()

self.nextState = self.initIonizationChamber

def tick(self):
self.nextState()

def initIonizationChamber(self):
self.chamber = IonizationChamber(self.hardware)
self.chamber.connect()
self.nextState = self.initOutputFile
self.applicationLayer.connect()

self.nextState = self.initMeasurementStorage

def initMeasurementStorage(self):
self.measurementStorage.connect()

def initOutputFile(self):
self.logFile = open('data.csv', 'w')
self.logFile.write("Time,Counter,DMM\n")
self.nextState = self.getMeasurementFromIonizationChamber

def getMeasurementFromIonizationChamber(self):
self.deviceMeasurement = self.chamber.getMeasurement()
self.deviceMeasurement = self.applicationLayer.getMeasurement()

self.nextState = self.saveMeasurement

def saveMeasurement(self):
now = datetime.datetime.now()
self.logFile.write("{0},{1}\n".format(
now, self.deviceMeasurement))

self.logFile.flush()

self.measurementStorage.saveMeasurement(now, self.deviceMeasurement)
self.nextState = self.showMeasurementToUser

def showMeasurementToUser(self):
print("{0}".format(self.deviceMeasurement))

self.nextState = self.getMeasurementFromIonizationChamber
23 changes: 23 additions & 0 deletions Software/DataAcquisition/transport_layer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@


class InvalidCRC(Exception):
pass


class MissingFrame(Exception):
pass


class InvalidMsgLength(Exception):
pass


class TransportLayer:
def __init__(self, physicalLayer):
self.physicalLayer = physicalLayer

def connect(self):
self.physicalLayer.connect()

def getFrame(self):
return self.physicalLayer.getData()
Loading

0 comments on commit f562f85

Please sign in to comment.