CT Scanner Week #4 – 1/31/2020

Week #4

Javier and Nicholas J. Holden

This week consisted of a lot of frustration. Whenever we fixed our servo, the stepper would stop working. When the stepper was fixed, the servo would stop working. We thought there may be a shortage somewhere on the Arduino with a wire touching the board. We also edited the code significantly to see if the issue was code-based and resorted to using the example stepper and servo motor code as a baseline test. The final solution ended up being restarting the Arduino multiple times and crossing our fingers. The solution worked. Upon fixing the system, we rewrote the Arduino code for increased resolution by decreasing both stepper and servo angle to one-degree rotation per sweep and fixing of the rotation of the stepper such that it would rotate fully for each angle of the servo sweep. Once this was done, we then began the process of gathering the data from a full sweep of the CT and importing and saving the data into Matlab. 

The next step was to measure and input the different inputs in MATLAB in order to create the reconstructed model of our phantom. The code would be based on the CT recon template provided by Dr. Grissom. 

Question: What is the fan angle of your scanner? How many projections will you acquire across this angle, given the resolution with which you can move your servo?

Answer: The fan angle of our scanner was 140 – 55 = 85 degrees. We plan to acquire 17,000 projections. This number was gathered by multiplying the fan angle by the stepper angle. 85 * 200 = 17,000!

It was a short week, but it was filled with a lot of problem solving and adventure. Something that Javier and Nicholas J. Holden aren’t afraid to seek out!

The video below demonstrates the stepper and servo in action collecting data points.

IMG_1047

Below is the code for our Arduino. This update correctly causes our servo and stepper to function. We did two sweeps to increase our Signal-to-Noise ratio.

#include <Servo.h>

#include <Wire.h>

#include “utility/Adafruit_MS_PWMServoDriver.h”

#include <Adafruit_MotorShield.h> 

 

// Setting up pins and angles for the motor

int servopin = 10;

Servo servo;

int angle = 0;

 

// Create the motor shield object with the default I2C address

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// Connect a stepper motor with 200 steps per revolution (1.8 degree)

// to motor port #2 (M3 and M4) 

Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

 

void setup() {

  // Opens the serial port

  Serial.begin(9600);

  AFMS.begin();  // create with the default frequency 1.6KHz

  // Sets up setting for the servo and stepper motor

  servo.attach(servopin);

  myMotor->setSpeed(60);  // 10 rpm  

}

 

void loop() {

  // Signals to Matlab to begin the collection of data

  Serial.println(“Start”);

  // Increments through servo angle one at a time

  for(angle=55; angle<140; angle+=1){

    servo.write(angle);

    delay(15);

    // Full rotates stepper and gathers data at each stepper angle

    for(int step=0; step<200; step+=1){

      double sensorvalue = analogRead(A2);

      double pot = analogRead(A3);

      Serial.print(step);

      Serial.print(“,”);

      Serial.print(angle);

      Serial.print(“,”);

      Serial.print(sensorvalue/1023*5);

      Serial.print(“,”);

      Serial.println(pot/1023*5);

      myMotor->step(1, FORWARD, MICROSTEP); 

    }

  }

  // Increments through servo angle one at a time

  for(angle=140; angle>55; angle-=1){

    servo.write(angle);

    delay(15);

    // Full rotates stepper and gathers data at each stepper angle

    for(int step=0; step<200; step+=1){

      double sensorvalue = analogRead(A2);

      double pot = analogRead(A3);

      Serial.print(step);

      Serial.print(“,”);

      Serial.print(angle);

      Serial.print(“,”);

      Serial.print(sensorvalue/1023*5);

      Serial.print(“,”);

      Serial.println(pot/1023*5);

      myMotor->step(1, FORWARD, MICROSTEP); 

    }

  }

  // Signals to Matlab to end the collection of data

  Serial.println(“End”);

  delay(10000);

}

 

 

IR CT Scanner Update #4

Update #4

Danielle, Antonio, Hannah

This week, we captured our CT data in a text file and reconstructed it. The shape of our sinogram looks accurate, but there is higher intensity light observed at lower degrees (0 to 30 degrees), which is indicated by the yellow color, and lower intensity light observed at higher degrees, which is indicated by the aqua color. These findings show that one side of the CT scanner is more exposed to light, probably from the classroom window, than the opposite side. Our reconstructed image looks somewhat accurate, but we suspect that our measurements are undersampled. Next week, we will increasing the number of samples/time period and will collect data with the blinds closed and a tarp covering the scanner. Below are images of our sinogram and reconstructed image.

sinogram

Figure 1: Sinogram

Reconstructed Image

Figure 2: Reconstructed image

Question: What parameters of your scanner and scan method influence resolution? Investigate these.

We have the servo motor moving the swing arm 90 degrees and the stepper motor moving once when the swing arm finishes its rotation. We should switch the order of the servo motor and the stepper motor so that the stepper motor rotates 270 degrees and then the swing arm moves once. This would increase the resolution because the stepper motor is more stable than the servo motor, so it would reduce the probability of motion artifacts.

We also expect the size of our detector and the distance between the fan beam and motors to affect our resolution. We plan to investigate all of these parameters next week and see how the resolution improves.

Infrared CT Update 3: January 28, 2020

Morgan Kinney, Tanner Hoppman, Jude Franklin

This week we were able to connect the motors to our Arduino circuit. We spent our time programming both the stepper motor and servo arm to work in tandem. This was particularly tricky because we had to refine their range of motion, but we had issues with getting their code to work without interfering with each other. When adding the stepper motor, the normally functioning servo started malfunctioning. We concluded this week with fully functioning code for all the mechanical components as seen in the video under Element 1 and the image of the Arduino code in Element 2. The next step will be to code the matlab programming for the imaging of the scanner itself.

Element 1: Video of functioning servo arm and stepper motor

servoarmsteppermotor

Element 2: Image of Arduino code to program the moving parts

imagingcode128

Question: Why is the fan2para() function needed?

Answer: The projection data obtained from our IR CT device is fan-beam projection data, and the matlab program is set up to reconstruct parallel beam projections. Thus, fan2para is needed to convert our data from fan-beam to parallel beam in order to be reconstructed into the final images.

IR CT Update #3

Update #3 

Danielle, Hannah, Antonio

    Last week we predominantly worked on the software and data acquisition. Because we were having difficulty with the serial communication between the Arduino and Matlab, we decided to write Python code that would perform the serial communication instead. Below is the Python code that communicates with the Arduino from the serial port. The Python code reads successive lines from the serial port as the Arduino is taking data and then stores the projection angle data into the array byte_data. Because the data the Arduino prints to the serial port is in byte form, the script decodes the byte data, splits the values after each comma, and then stores them in an array. Once all of the data is received, this code writes the array to a text file on the users computer in ASCII format which is important. Because the text file is in ASCII format, matlab can very easily load the data from the text file directly into an array using the load() command. From here, the matlab code below can be used to perform filtered backprojection and reconstruct the image.

Question

What is the finest resolution with which you can move the swing arm (servo) and stage (stepper motor)? What does this dictate about the finest spatial resolution of your image

The finest resolution with which we can move the servo is 1.8 degrees and for the stage, 200 steps per resolution. This means that the finest spatial resolution is determined by whichever component has the largest angle of rotation.

Question

The servo has an extra (white) wire on it, that reads out its built-in position potentiometer, which you can use to record the servo’s actual position (rather than just its intended position). Is your image reconstruction improved by using this value instead of the intended value? 

Our image reconstruction is improved.

Our Python code

Screen Shot 2020-01-27 at 11.19.52 PM

Our Matlab code

Screen Shot 2020-01-27 at 11.20.01 PM

IR CT Week 3 Update

Alex Boyd, Myron Mageswaran, Maggie Ford

This week the group refined the cable management and secured the arduino and breadboard to the scanner frame (shown below). The group also increased the fan angle to now sweep 100 degrees in order to image the entire phantom.  The position of the stepper motor and servo are now being read by MATLAB and being placed in individual vectors for interpretation by the image reconstruction script.  Lastly, the image reconstruction script parameters were set by the group.  The students still need to set the inputs to the final image creation function but the initial parameters have been set as seen below.

 

Input Parameters for Reconstruction

Screenshot (2)

Refined Cable Management

IR CT Scanner

Question: What parameters of your scanner and scan method influence resolution? Investigate these.

  • The size of the servo step between reads influences resolution as well as the distance between the photodiode and IR LED because this changes the focus by changing the scatter angles that are read by the system.

Question: What is the smallest feature or line pair that you can resolve?

  • The actual smallest feature we can resolve will be found (and this answered again next week) when an image is constructed but the resolution will be limited by those factors mentioned in the above question such as servo step size and the size of the focal point of the photodiode.

IR CT Scanner Week 3 Update

Hunter Spivey and Aayush Gupta:

This week be managed to connect our stepper motor to our adafruit motorshield via the M1 and M2 ports and run it via our arduino code. We initially had connected it via the digital pins, but eventually rewired it. Following this we began to work on reading our output from out current-to-voltage converting circuit into our arduino’s analog input, and displaying it on arduino’s built in serial monitor. We were able to successfully do this, and we confirmed that the displayed values would change if we blocked the incident IR light on the photodiode. After this we then moved on to connecting our fan arm servo to the arduino board, and writing the code to move it in the correct direction. We initially struggled to connect the servo properly, but after working with it for a bit, were able to connect it and write the code to move it over a specified angle. Finally we worked on cleaning up our wire connections to make it a little bit tidier and less all over the place.

Our next goal is to work on interfacing the arduino serial monitor output with Matlab so we can use the measured voltage values to try and reconstruct an image of the phantom.

Video:

Below is a video of where our scanner was at when we finished by the end of last week. We have changed the code so that the stepper motor only takes one step per sweep of the fan arm, although this video does not reflect this change.

IMG_3048

Code:

Additionally, we have modified the code to be cleaner, as well as to address the change in the stepper motor previously described. Images of the new code can be found below.

Week 3 Code #1Week 3 Code #2

Question: 

The servo has an extra (white) wire on it, that reads out its built-in position potentiometer, which you can use to record the servo’s actual position (rather than just its intended position). Is your image reconstruction improved by using this value instead of the intended value?

Answer: 

Because this would give us the actual position of the fan arm as opposed to what we told it it should be at, then yes, using the white feedback wire could potentially improve the accuracy of our servo’s position recording. However, since we are not moving the fan arm at a very high rotational speed, the use of this more accurate feedback wire isn’t necessary as our servo should have more than enough time to reach the position we instruct it to. If the servo as a whole is off on its positioning, then it could become an issue, but for our current purposes it isn’t required.

 

 

Infrared CT Scanner Update 3

Blog Post Week #3: Imaging Instrumentation Infrared CT Lab
Jorie Budzikowski, Stephanie Molitor, and Rachel Welscott

Quote of the Week:

“Do you know what this delay is for?”
“I don’t know, but it’s probably not important. You can delete it.”
*deletes delay*

“OKAY so that delay was VERY important!”

This week, we were able to tackle several parts of the Infrared CT Scanner including the servo rotation, the stepper motor rotation, and the Matlab readout of photodiode voltage from the Arduino.

The Servo and Stepper Rotation:

With the success of the voltage readouts from our circuit, we have since turned our attention to the Servo that controls the rotating arm of the scanner. We have programmed the Servo (via Arduino) to move the rotating arm, and have optimized the speed and delay during rotation. The code that controls the Servo rotation is shown in the image below. We have also programmed the stepper motor to move the phantom with a step size of 1.8 degrees between each full sweep of the servo arm. To complete a full 360 degree image of the phantom, the stepper motor must rotate the phantom 200 times. The combined movements from the Servo and the stepper motor are shown in the video below. We have also altered the Arduino code to display the output voltage and sweeper arm position on the serial monitor for each data point.

Video one: The Servo has been programmed to rotate the sweeper arm around the phantom, and the stepper motor takes (very small) steps between each full sweep.

Image One: The Arduino code that controls both Servo and stepper motor rotation. This code also writes the output voltage and corresponding sweeper arm position to the serial monitor.

combined code

The Matlab readout of the photodiode voltage from the Arduino:

Matlab is a crucial element to this CT Infrared Scanner because it is the way that we will ultimately analyze the results from our scan. Our code should read out and store the voltage value at each point for both the sweeper arm and gantry rotation. These readout values will be translated into binary numbers and be displayed as black or white on our image reconstruction. Our preliminary code, shown below, is used to read and store the output voltage for each step of our Servo and stepper motor.

Image Two: The Matlab code that stores the output voltage value for each step.

matlab

Questions we set out to answer this week:

  1. What is the finest resolution with which you can move the swing arm (servo) and stage (stepper motor)? What does this dictate about the finest spatial resolution of your image?
    1. The smallest step size that we can take with the stepper motor is 1.8 degrees. The smallest step size we can take with the servo is 1 degree. This dictates that the finest spatial resolution of our image is 1.8 degrees since this is the larger of the two component resolution values.
  2. The servo has an extra (white) wire on it, that reads out its built-in position potentiometer, which you can use to record the servo’s actual position (rather than just its intended position). Is your image reconstruction improved by using this value instead of the intended value?
    1. The position value of the servo is an arbitrary position value. As long as we know where the designated 0 position is located, it does not really matter whether or not we know the actual position of the servo. Thus, the white wire does not add much information to our system.
  3. What parameters of your scanner and scan method influence resolution? Investigate these.
    1. The parameters that influence resolution are the step size of the servo motor and the time the servo motor has to record a section of the “image” in between steps.

CT Scanner Week #3 – 1/24/2020

Javier and Nicholas J. Holden

This week, we tried to make our work more aesthetically pleasing and efficient by securing the wires as well as both the breadboard and Arduino to the metal bar above the servo. The breadboard was fashioned with a double-sided adherence tape and the Arduino was with Velcro. This allows the ability to attach and detach the Arduino which is useful. In addition, many wires were shortened and also shrinking tape was attached to the various junctions to not leave those connections exposed.

We encountered the problem of the servo shaking in place and not moving. The problem was solved by reworking part of the code written for it and moving a pin to a different analog input. It now works as intended; however, as one problem ends, another begins. The stepper is our primary challenge. While all the correct wires are attached to our Arduino, the code is not allowed to run. Many solutions were attempted such as just moving utilities into the folder to allow the code to work as well as running the test code. In a desperate attempt, we disconnected our servo from our stepper. With this connection severed, the stepper began to rotate as programed below. It was concluded that for some reason our servo was interfering with our stepper. The working theory is that the servo may be drawing too much current. Our solution was to install a new servo and see if that will work. But before that solution was carried out, we noticed that the servo control wire may be stealing tons of current. So we attempted to resolder and attach the control wire back into the 3 pin set up because the control wire wasn’t connected to the power wires. This did not work, so the original solution to replace the servo was taken. \

Unfortunately, when we added the new servo, we encountered the same problem again: the stepper stopped rotating. Our next idea was to restart the Arduino. This still did not fix anything. In an absolutely desperate attempt, we had to use a different pin for our potentiometer from the servo. That was the problem. However, this solution broke the servo. We believe the same issue is at play though and so only need to find another analog pin to get the system to work.

Below are an attached photo and video of the updated machine. Photo 1 is a picture of the current system. There is a marked improvement to the design compared to last week. Video 1 displays the servo and stepper in action. After many weeks, we have finally achieved the desired function from both of the devices. Our next steps are to fine-tune the system and create MATLAB code to be able to do reconstruction for the information collected from the photodetector as well as fine-tune the Arduino code for this same process. The Arduino code needs to be updated to better replicate the fan angle as well as provide measurements for each of the fan angle. 

Below is our code for the Servo motor and the Stepper

#include <Servo.h>

#include <Wire.h>

#include “utility/Adafruit_MS_PWMServoDriver.h”

#include <Adafruit_MotorShield.h> 

int servopin = 9;

Servo servo;

int angle =0;

 

// Create the motor shield object with the default I2C address

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// Connect a stepper motor with 200 steps per revolution (1.8 degree)

// to motor port #2 (M3 and M4) 

Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

 

void setup() {

  // put your setup code here, to run once:

  Serial.begin(9600);

  servo.attach(servopin);

  AFMS.begin();  // create with the default frequency 1.6KHz

  myMotor->setSpeed(60);  // 10 rpm  

}

 

void loop() {

  // put your main code here, to run repeatedly:

  for(angle=70; angle<230; angle++){

    servo.write(angle);

    double sensorvalue = analogRead(A2);

    double pot = analogRead(A3);

    Serial.print(sensorvalue/1023*5);

    Serial.print(“,”);

    Serial.println(pot/1023*5);

    myMotor->step(50, FORWARD, MICROSTEP); 

    delay(50);

  }

  for(angle=230; angle>70; angle–){

    servo.write(angle);

    double sensorvalue = analogRead(A2);

    double pot = analogRead(A3);

    myMotor->step(50, FORWARD, MICROSTEP); 

    Serial.print(sensorvalue/1023*5);

    Serial.print(“,”);

    Serial.println(pot/1023*5);

    delay(50);

  }

  delay(1000);

}

Photo 1 - Improved CT System

Photo 1 – Improved CT System

Please click the link to the right to watch the video of the CT Stepper in action – IMG_1004

 

Question: Which way does your photodiode need to be oriented to get a positive output voltage?

Answer: In order for the photodiode to receive a positive output voltage, it needs to be oriented so that the cathode is facing the op-amp, and the anode is facing ground. You will get a positive voltage that way.

Infrared CT Update 2: January 21, 2020

Morgan Kinney, Tanner Hoppman, Jude Franklin

This week we were able to continue troubleshooting our circuits. By using a multimeter, we were able to determine if the voltage at the input and outputs of the circuit was reactive to the LED and IR photodiode (Element 1). Initially, we had the setbacks of the IR LED being shortcircuited, thus we had to re-solder the connections. After we were able to determine a proper relationship between the distance between the photodiode and the LED and their relative output voltage by changing our feedback resistor to a megaohm, we focused on uploading Arduino code to read the analog input and translate that into the Serialread function. Thus, we were able to see the live read-outs of the voltage values on the serial monitor as the IR LED and photodiode distance changed. We left off attempting to transfer the serial monitor values into Matlab where they will be much more useful for image reconstruction (Element 2).

Element 1: Placement of the breadboard and Arduino on the frame. This location will allow for the circuits to remain intact while the servo arm moves during image acquisition.

irct

Element 2: Arduino and Matlab code used to communicate serial port data with Matlab.

Arduino code:

byte incomingByte1;

void setup(){

 pinMode(2,OUTPUT);

 Serial.begin(115200);

 Serial.println(“Ready”);      

}

void loop() {

 digitalWrite(2,LOW); //turn off LED

 delay(500);

if (Serial.available() > 0) {

digitalWrite(2,HIGH); //flash LED everytime data is available

delay(500);

incomingByte1 = Serial.read(); //read incoming data

Serial.println(incomingByte1,HEX); //print data

}

}

 

Matlab code:

clear

clc

s=serial(‘COM7’,‘BaudRate’,115200);

fopen(s);

readData=fscanf(s) %reads “Ready”

writedata=uint16(500); %0x01F4

fwrite(s,writedata,‘uint16’) %write data

for i=1:2 %read 2 lines of data

readData=fscanf(s)

end

fclose(s);

delete(s);

 

Question: How can you limit current into the LED to avoid damaging it?

Answer: By connecting a resistor in series with the LED and the Arduino power source, the current of the total circuit is reduced, which decreases the chances of damaging the LED. This does, however, decrease the voltage drop across the LED, which decreases its brightness, but using a moderately low resistor value (1kOhms) allows this effect to be minimal.

1/20/20 Week #2 Update

CT Scanner Blog Post Week #2

Aayush Gupta and Hunter Spivey

This week we were able to successfully design and implement a circuit that is used to power the IR LED using the Arduino Uno’s 5V supply. Moreover, we were able to incorporate a current-to-voltage op amp circuit that converts the photodiode current into a voltage signal, which is then sampled through the Arduino. We were able to ascertain that the current-to-voltage circuit was working properly by covering and uncovering the photodiode when the system was hooked up and then by discerning, through the use of a multimeter, that when it was covered the voltage values printed on Arduino were significantly lower (0-0.5V) than those when it was left uncovered (4.3-4.5V).

In the following week we will focus on programming the Arduino to move the stepper motor and server across a certain range, as well as collecting the position versus photodiode voltage data as it moves. We will also look into producing the MATLAB script that reads the Arduino’s serial port and records the values that it receives. 

Image #1: This image shows the current-to-voltage and Arduino receptor circuits optimally set up. 

Week 2 Circuit

Image #2: This image exhibits the Arduino code needed to correctly print the voltage outputted from the op amp circuit.

Week 2 Code

Below are the answers to the questions for this week:

Question: How can you limit current into the LED to avoid damaging it?

We limited the current into the LED to avoid damaging it by inserting a current loading pin in the circuit, placed between the 5 volt output and the LED, this caused the LED to not have too much current flowing into it and remains usable.

 

Question: Does the value of the current-limiting component affect the amount of light you detect with the photodiode? Can you optimize that?

The value of the current-limiting resistor does affect the amount of light that is detected by the photodiode, with the presence of a higher resistor causing a less luminescent lightbulb. This can be optimized by taking into account the voltage needed to power the lightbulb and using that value figuring out what the voltage across the current-limiting resistor should be. By using that voltage and the current from the Arduino, we can easily deduce the optimal resistance value of the component.