If anyone else would like to help, here’s my current Arduino code in full. It’s adapted from the version which prints stuff to the attached screen, so there’s a lot of commented out code.
// setup the screen and stuff
/*#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_DC 6
#define TFT_CS 7
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);*/
//setup motor shield
#include <Adafruit_MotorShield.h>
//setup motors
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *aziDrive = AFMS.getStepper(200, 1);
//setup servos
#include <Servo.h>
Servo elevDrive;
//setup the sensor
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
//changeable variables are here
const int aziRange = 10; //azimuth total sweep range (in motor steps * aziRes (200 per 360 degrees))
const int aziRes = 1; //azimuth resolution
const int elevRange = 3; //elevation total sweep steps
const int elevRes = 4; //elevation resolution (in degrees) (make sure (elevRange*elevRes) <= 170)
const int numReadings = 2; //number of samples per scan
const float maxDepth = 1000.0; //maximum displayed depth (must have .0 to work)
//const float minDepth = 300.0; //minimum displayed depth (must have .0 to work)
//non-changeable setup variables are here
int LiDARdata[aziRange][elevRange];
//const int Height = 240;
//const int Width = 320;
void setup() {
Serial.begin(9600);
Wire.begin();
while (!Serial);
//Serial.println("Mini-LiDAR Program Start!");
/*tft.begin();
tft.setRotation(3);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.fillScreen(ILI9341_BLACK);*/
elevDrive.attach(10); //attach the elevation servo to pin 10
elevDrive.write(10);
if(!AFMS.begin()) {
//Serial.println("Could not find Motor Shield.");
while (1);
}
//Serial.println("Motor Shield found.");
sensor.setTimeout(500);
if (!sensor.init()) {
//Serial.println("Failed to detect and initialize sensor.");
while (1) {}
}
//Serial.println("Sensor found.");
sensor.startContinuous();
//Serial.println("Initialization complete. Waiting for positioning.");
//tft.print("Initialization complete. \nWaiting for positioning.");
delay(3000); //wait for user to position the stepper
aziDrive->setSpeed(1);
aziDrive->step(aziRange/2, BACKWARD, MICROSTEP); //move motor back by half length to starting position
//tft.fillScreen(ILI9341_BLACK);
//tft.setRotation(1);
}
void loop() {
elevDrive.write(10);
for(int elevStep = 0; elevStep <= elevRange; elevStep++) {
//Serial.print("Starting elevation sweep ");
//Serial.println(elevStep);
elevDrive.write((elevStep * elevRes) + 10); //elevate by a step and add 10 deg for power usage reasons (duplicated step to fix the second sweep not elevating bug)
for (int aziStep = 0; aziStep < aziRange; aziStep++) {
//Serial.println(aziStep);
int total = 0;
for(int i = 0; i < numReadings; i++) {
total = total + sensor.readRangeContinuousMillimeters();
}
float average = (total/1.0)/(numReadings/1.0);
//Serial.println(average);
LiDARdata[aziStep][elevStep] = average; //store LiDAR data
aziDrive->step(aziRes, FORWARD, MICROSTEP); //step azimuth forward by 1
}
//Serial.println("Azimuth moving back to start...");
elevDrive.write(((elevStep + 1) * elevRes) + 10); //elevate by a step and add 10 deg for power usage reasons (added 1 to move during azimuth reset)
aziDrive->step(aziRange*aziRes, BACKWARD, MICROSTEP); //move azimuth back to starting position
}
//Serial.println("Elevation moving back to start...");
int elevStep = 0;
elevDrive.write(elevStep + 10); //move elevation back to starting position
for(int j = 0; j <= elevRange; ++j) { // loop through array's rows
for(int i = 0; i < aziRange; ++i) {// loop through columns of current row
/*
float grayScale = 1; //this sets the grayScale value to 0 if the sensor reading was outside of the set maxDepth instead of it being that weird yellow color
if (LiDARdata[i][j] < maxDepth) {
grayScale = 1 - (LiDARdata[i][j] / maxDepth);
} else {
grayScale = 0;
}
//float grayScale = 1 - (LiDARdata[i][j] / maxDepth);
//float grayScale = 1 - (((LiDARdata[i][j] - 0.0) * (maxDepth - minDepth) / (1300.0 - 0.0) + minDepth) / maxDepth);
unsigned int colorHex = ((unsigned int)(0x1F * grayScale) << 11) \
| ((unsigned int)(0x3F * grayScale) << 5) \
| (unsigned int)(0x1F * grayScale);
tft.fillRect((i*(Width/aziRange)), (j*(Height/elevRange)), (Width/aziRange), (Height/elevRange), colorHex); //print data to screen in blocks
*/
Serial.print(LiDARdata[i][j]); //print data to serial
Serial.print("\t"); // start new column of output
}
Serial.print("\n"); // start new line of output
}
Serial.println("End");
delay(1000);
}
Here’s my current attempt to read the serial data from the Arduino in Processing:
//MiniLiDAR companion display app
//pl4sma2389
//Credits to: GLV
import processing.serial.*;
Serial arduino; // Create object from Serial class
String serialData; // Data received from the serial port
int aziRange = 10; // Must be the same as on Arduino
int elevRange = 3; // Must be the same as on Arduino
int[][] LiDARdata = new int[aziRange][elevRange]; //Serial data formatted into an array
int data, count;
boolean dataSetReady;
int Width = 320;
int Height = 240;
void setup() {
String portName = Serial.list()[2]; // 2 = COM3 = Arduino
println();
arduino = new Serial(this, portName, 9600);
arduino.stop();
arduino = new Serial(this, portName, 9600);
size(Width, Height);
}
void draw() {
if(arduino.available() > 0) {
serialData = arduino.readStringUntil('\r');
if(serialData != null) {
serialData = trim(serialData);
println(serialData);
String[] dataIn = splitTokens(serialData, "\t");
if(dataIn[2].equals("End")) {
println();
println("End");
println();
data = 0;
}
}
}
}
And here’s my code to write some hand-formatted data to the screen in Processing:
int[][] LiDARdata = { {335, 478, 483, 467, 463, 443, 404, 411, 410, 385},
{455, 450, 445, 440, 435, 422, 412, 397, 389, 389},
{477, 474, 472, 462, 446, 429, 416, 412, 398, 392},
{478, 483, 467, 463, 443, 404, 411, 410, 385, 357} };
int aziRange = LiDARdata[0].length;
int elevRange = LiDARdata.length;
int Width = 320;
int Height = 240;
int maxRangeDisplayed = 500;
void settings() {
size(Width, Height);
}
void setup() {
frameRate(2);
println(aziRange);
println(elevRange);
}
void draw() {
colorMode(RGB, maxRangeDisplayed, maxRangeDisplayed, maxRangeDisplayed);
background(1);
for (int i = 0; i < elevRange; i++) {
for (int j = 0; j < aziRange; j++) {
fill(maxRangeDisplayed - LiDARdata[i][j]);
stroke(maxRangeDisplayed - LiDARdata[i][j]);
rect((j*(Width/aziRange)), (i*(Height/elevRange)), (Width/aziRange), (Height/elevRange)); //print data to screen in blocks
}
}
}