Levitation Machine Help

I am building the levitation machine found on page 159 in this book: https://www.scribd.com/doc/176638746/15-Dangerously-Mad-Projects-for-the-Evil-Genius

Everything is wired up correctly (I think), but I have two problems.

  1. The IR sensor (signal on A0) is at about 4.7 V when nothing is in the way, and 5.11 V when blocked. I need help finding out how to tell the code to read A0 more sensitively and register A0 = 4.7 V as nothing in the way of the sensor, i.e. more current through the coil to raise the object. (If I pull the pin out from A0 and force it to be 0 V, then I get a gate voltage from pin 11 and some current through the coil).

  2. But when I put 0 V on A0, I get about 1.5 V out of pin 11 (to the gate of my transistor). How do I make the magnitude of this voltage bigger? Because I separately determined that I will need about 3 V on the gate to get enough current to hold the object up.

Here is the code:

// Project 13 - Anti-gravity
// 15 Dangerous Projects for the Evil Genius

#define coilPin 11
#define irPin 13
#define sensorPin 0

int A = 2;
// Adjust B to improve stability
int B = 60;
int C = 20;
int D = 1000;

int maxPower = 255;
long powerCountThreshold = 300000;
int objectPresent = 0;
int monitoring = false;

void setup()
{
pinMode(coilPin, OUTPUT);
pinMode(irPin, OUTPUT);
pinMode(sensorPin, INPUT);
Serial.begin(9600);
Serial.println("Ready");
Serial.println("m - toggle monitoring");
Serial.println("B - increase B");
Serial.println("b - decrease B");
}

void loop()
{
static int count = 0;
static int oldPosition = 0;
static int ambient = 0;
static long powerCount = 0;
count ++;

if (count == 1000)
{
ambient = readAmbient();
count = 0;
objectPresent = (powerCount < powerCountThreshold);
powerCount = 0;
}
int raw = 1024 - analogRead(sensorPin);
// position from top (0) of sensor region to the bottom (650)
int position = raw - ambient;
// positive value means going downwards, negative going upwards
int velocity = position - oldPosition;
int power = position / A + velocity * B + C;

powerCount += power;
oldPosition = position;

// clip
if (power > maxPower) power = maxPower;
if (power < 0) power = 0;

checkSerial();

if (monitoring)
{
Serial.print(position); Serial.print(",");
Serial.println(velocity);
}

analogWrite(coilPin, power * objectPresent);
delayMicroseconds(D);
}

int readAmbient() //todo try speding up delay in micros
{
digitalWrite(irPin, LOW);
// allow time for LED and phototransistor to settle
delayMicroseconds(100);
int ambient = 1024 - analogRead(sensorPin);
digitalWrite(irPin, HIGH);
return ambient;
}

void checkSerial()
{
if (Serial.available())
{
char ch = Serial.read();
if (ch == 'm')
{
monitoring = ! monitoring;
}
if (ch == 'B')
{
B += 5;
Serial.println(B);
}
if (ch == 'b')
{
B -= 5;
Serial.println(B);
}
}
}

Thanks a bunch!

  1. The IR sensor (signal on A0) is at about 4.7 V when nothing is in the way, and 5.11 V when blocked.

Given a 5V power source, any value above 5 seems unlikely. If there is a difference of only 0.41 V between blocked and unblocked, I'd suggest that there might be something wrong with the hardware or the wiring (or the interpretation of the data that you did not explain how you obtained).

Try ditching most of that code. Simply read the sensor and print the value, with a 500 millisecond delay() at the end of loop(). Do you get reasonable data?

The problem is I can't tell from the code what voltage the sensor is considered to be open (nothing in the way). Which value is that?

The problem is I can't tell from the code what voltage the sensor is considered to be open (nothing in the way). Which value is that?

The only thing I see that reads a variable voltage is:

  int raw = 1024 - analogRead(sensorPin);
  // position from top (0) of sensor region to the bottom (650)

So, apparently, the sensor is supposed to return 0 when completely open and 1024 when completely blocked. The value computed is then used to determine the power required. More power == stronger repulsion, unblocking more of the sensor. Less power == weaker repulsion, blocking more of the sensor.

void loop()
{
   Serial.print(analogRead(sensorPin));
   delay(100);
}

Do you get reasonable values as you completely block, partially block, and completely expose the sensor?

Until then, none of the rest of the code matters.

I fixed the sensor problem. Now when there is nothing in the way we get gate voltage and when it is blocked the gate voltage turns off.

Now the only problem is the magnitude of the gate voltage. How do I make it higher so we can get more power into the coil?

Now when there is nothing in the way we get gate voltage and when it is blocked the gate voltage turns off.

That sounds like a digital device - off or on. The one that the author used appears to have been an analog device.

Are you really seeing just 0 or 1023 from analogRead()?

No it is an analog reading, about 2 V when object is around half way in front of the sensor. We just have a power problem now.