CT Scanner Week #8 – 2/28/2020

Week 8

Javier and Nicholas J. Holden

This week was spent working with the radio in order to try and get the radio to release a pulse for the ultrasound. The beginning of the week was primarily about getting used to the GNUradio by doing the different tutorials given by the software and viewing the results using the oscilloscope. Once these were finished, we attempted to create the pulse wave needed for the ultrasound. We figured out the parts needed in order to create the wave. We did encounter some issues in this process primarily because of getting the pulse duration just right by deciding the timings of the different pieces and amounts.  

 

Nicholas J. Holden persevered on Thursday due to teammate and hardware specialist, Javier, having to attend to a sensitive matter. The beginnings of the Arduino code was formed in an effort to begin work to move the ultrasound sensor around the artifact. Unfortunately, this did not get too far in the development stage. Nicholas J. Holden then tried to work on the GNUradio with the software associated with the device. Little progress was made, however, much was learned from Grissom who gave a short lecture to two groups about the overall direction he wanted groups to go with the software.

Figure 1 – illustrates the sinusoidal wave achieved with the radio.

IMG_1291 copy

Figure 2 – illustrates the software we have working with to generate the appropriate waves.

IMG_1305 copy

We are currently trying to survive the Coronavirus and will continue to update this blog and the continuation of our work.

Question: What is the role of the quarter-wave line?

This allows the path to the Rx port to seem like an open or closed circuit by changing the impedance of the line. This wire has to be a quarter of the length of the wavelength of the wave being used.

 

CT Scanner Week #7 – 2/25/2020

Week 7

Javier and Nicholas J. Holden

This week was spent on trying to make sure that the TR switch was constructed and functioning properly. Figure 1 shows the soldered circuit. Upon testing the circuit for the first time, we discovered that the inductor was not properly soldered onto the board. This in turn created a break in circuit at the inductor. This was incredibly frustrating because they were difficult to replace due to being delicate. After solving this problem, we then tested that the circuit was continuous. Once this was confirmed we resumed testing for return loss. We encountered a problem when we first did the testing, but we discovered that the error wasn’t from the TR switch but rather the antenna analyzer. This was discovered by testing a working TR switch and observing a very low return loss for Tx-Out with a 50 Ohm load on the Rx port. Figure 2 displays the outer shell of the circuit that was attached with the ports labelled. Upon switching out the analyzer, the return loss was then collected for a variety of situations. This includes a -9.14 dB return signal with the analyzer connected to Tx-Out and a 50 Ohm load on the Rx port. The reverse of this situation was also tested and returned -9.27 dB. This was good as it should be symmetric. When the 50 Ohm load is removed, the return loss in both situations are 0.64 and 0.62 dB. Finally the Tx-In port was tested and had a return loss of .02 dB which is what we expected to occur. Next week, we will get started on running the GNURadio and SDR in order to create a pulse signal as well as familiarizing ourselves with the GNURadio.    

Figure 1

Figure 1

Figure 2

IMG_1245 copy

Question: How would you express this mathematically?

Answer: You would express this as an infinite amount of impedance preventing the flow of current. This makes the circuit appear as an open circuit.

 

CT Scanner Week #6 – 2/15/2020

 

Week 6

Javier and Nicholas J. Holden

Sadly, this is our last week looking and working with our homemade CT machine before we decided it needed to be destroyed. We ran our last data collection on several different phantoms for the report. We felt accomplished because we had tangible results. We tried to fully reconstruct the image but ran into some problems because the resulting image looked nothing like our phantom. After speaking with the Professor, we realized that we had incorrectly measured our dcm. Our previous thought was that it was the distance from the middle to the photodiode; however, it is the distance from the middle to the servo motor. We also played around with our servo center angle to try and correctly align our sinogram to the middle. Figure 1 demonstrates the finished sinogram. Notice how it is nicely aligned in the middle of the window. Figure 2 illustrates the reconstructed image of the phantom.

We also began our ultrasound lab. Our mold that was created last week turned out fantastic. The ice bath contributed to the success because of the lower temperature we were able to achieve before we stopped stirring. We also began to solder pieces to our electric board. I cannot begin to describe the frustration that Javier and I (Nicholas J. Holden) experienced when trying to solder the inductor to the board as it was a small and easily breakable component. Eventually, we were able to correctly solder it and were able to finish the TR switch. We still need to test the switch to ensure the TR switch is functioning like expected. 

 

Question: What values do you get for L and C? 

Answer: 1.59μH for the inductor and 636.5pF for the capacitor

Question: How close can you get to these values with the components we have (without, e.g. using multiple components in each position)?

Answer: We were able to get 1.5μH inductor and a 680pF capacitor.

 

Figure 1 – The sinogram

Figure 1

 

Figure 2 – Reconstructed image of our phantom

19202_phantom

CT Scanner Week #5 – 2/11/2020

Week 5

Javier and Nicholas J. Holden

This week was spent focused on collecting and reconstructing the data. Luckily, our machine appeared to be functioning correctly, and no adjustments were needed to the machine.

We decided to collect data in two ways: two sweeps with our servo while our stepper is rotating at 60rpm and then one sweep with the servo. When there’s two sweeps, the ctRecon template image looks like a mirror image. Instead of trying to do some fancy math, we decided to collect the data in the two prescribed ways. It makes the math and future reconstruction a little easier.

We also changed the phantom to ensure that our code was running accurately and the data collected was changing with each phantom. Unfortunately, we experienced an issue with our servo / arm in that it could not move backward on the metal arm overhang. This meant we were not allowed to photo larger phantoms because there physically wasn’t enough space. The issue appeared to be that the person who configured the metal arm had hammered in a nut to a bolt and NOT a slider. Such brute force resulted in the slider unable to move backward. After an annoyed sigh, we decided to replace the phantom with a smaller one. While running the program on the replacement phantom, we made our own homemade auger phantom. To ensure we were protected from the graphite particulates and the Coronavirus, we wore masks. 

After microwaving the mixture, we had to continually stir it and wait for the temperature to decrease. Figure 1 illustrates this action by Javier. It was imperative that the two substances didn’t separate. We decided to create a bucket of ice to place the mixture in because we needed the auger/graphite mixture to reach a low enough temperature; this was important because we wanted to stop stirring while ensuring that there was minimal separation with the graphite and auger powder. As seen in Figure 2, we McGuyver’d the contraption. A dead battery was placed on top of the phantom in an effort to submerge it more into the liquid mixture. Afterwards, we placed tape everywhere and left it in a bag. We are excited to see what will happen to our device next week.

Figure1Figure 1 – Javier stirring the graphite/auger mixture

Figure2

Figure 2 The graphite/auger mixture inside a bag. The white dead battery is visible on top  of the orange phantom that was submerged into the liquid

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: This would provide a more accurate measure of the servo angle but would require making sure that the servo is actually hitting all the positions in order to form the image. This may happen if there is something wrong with the servo and it is actually not hitting the right positions and would be visible with potentiometer voltages.

 

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);

}

 

 

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.

CT Scanner Week #2 -1/17/2020

Authors: Nicholas J. Holden and Javier

This week we were able to successfully build a working current-to-voltage circuit and get it working with both the photodiode and LED connected to the device. We determined the problem was with the photodiode which we suspect burned out during soldering. After replacing the photodiode, we were able to receive voltage measurements from the LED and photodiode. 

After completing this part of the build, we directed our attention to the servo. Our goal was to get it to rotate 180 degrees from the left and from the right. We encountered challenges from the Arduino Adafruit shield which had several ports that didn’t function. Once resolving this issue, we used code from last week to get the servo motor to rotate properly. We also finished porting of the Arduino data to Matlab allowing for the gathering of data from the device to be processed in Matlab. The code shown below opens a serial port and waits for a start and end string that allows it to read the data in between the start and endpoints. 

The next steps for this project are to consolidate the device to be more aesthetically pleasing and efficient with space. We will accomplish this by attaching the Arduino and breadboard to a metal beam above the servo. We also need to start writing the code for the processing of slices in Matlab as getting the rotation of the stepper motor to work and connected to the Arduino. 

Question: How can you limit the current to avoid damaging the LED in the output?

Answer: Place a current limiting resistor between the LED and the 5V pin to avoid overloading the LED.

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

Answer: The resistor does take away some of the voltage from the LED that can make the LED less bright. However, the LED is maximally powered at 1.2V, and the current drawn from the Arduino is around 20mA. This means the resistor should draw 3.8V which relates to 190 Ohms of resistance based on the current from the Arduino. This would prevent the burning of the LED without reducing brightness.

% open the serial port

s = serial(‘/dev/cu.usbmodem14401′,’Baudrate’,14400);

fopen(s);

% initializing variables

stepAngle = [];

servo_us = [];

servoAngle = [];

potVoltage = [];

diodeVoltage = [];

         

% listen for the begin statement

readString = ‘foo’;

while isempty(strfind(readString,’Start’))

    readString = fscanf(s);

end

 

disp ‘acq started!’

 

% read data until the end statement

while isempty(strfind(readString,’End’))

    readString = fscanf(s);

    if isempty(strfind(readString,’End’))

        % parse the string for data

        C = strsplit(readString,’,’);

        stepAngle(end+1) = str2num(C{1});

        servo_us(end+1) = str2num(C{2});

        servoAngle(end+1) = str2num(C{3});

        potVoltage(end+1) = str2num(C{4});

        diodeVoltage(end+1) = str2num(C{5});

        % report progress

        if ~rem(length(stepAngle),100) disp(sprintf(‘Stepper angle: %d’,stepAngle(end))); end

    end

end

 

disp ‘acq ended!’

 

% save the data

save data_phantom_19200 stepAngle servo_us servoAngle potVoltage diodeVoltage

 

% close the serial port

fclose(s);

 

Picture 1: The photo demonstrates the ideal placement of the Arduino and the breadboard. As you can observe, the length of the wires are too long and need to be shortened. 

IMG_0968 copy

Picture 2:  This picture not only offers another perspective but allows the viewer to see the artifact.

IMG_0967 copy