Skip to content

docs: Added automatic scalling for graphs #2708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,50 @@ Sign up for the latest updates and test new features early by joining our beta p
| Gas Sensor | Detects gases, including NH3, NOx, alcohol, benzene, smoke and CO2| :heavy_check_mark: |
| Robotic Arm Controller | Allows to control 4 servo motors of the robotic arm independently | :heavy_check_mark: |

## Robotic Arm Control

The Robotic Arm feature in the PSLab Android app allows users to control a servo-based robotic arm using the Pocket Science Lab hardware. This is ideal for educational robotics, DIY automation, and remote experiments.

# Key Capabilities

-Manual control of servo motors using sliders.

-Set angles precisely for each servo.

-Create custom movement profiles (position sets).

-Save/load profiles from local storage using internal database.

-Export/import profiles in JSON format.

-Replay saved profiles for automation.

# How to Use the Robotic Arm Screen

-Connect the PSLab device via USB.

-Go to Instruments > Robotic Arm.

-Use the sliders to move each servo (e.g., Base, Shoulder, Elbow, Gripper).

-Set desired positions for all servos.

-Tap Save Profile to store the current servo positions.

-Use Load Profile to retrieve saved movements.

-Tap Play to replay the selected profile.

# Saving and Loading Profiles

-Save: Stores the current servo angles into a named profile in local database.

-Load: Loads the servo angles from a selected profile and updates the UI.

-Export: Saves profile(s) to a .json file.

-Import: Load external JSON files to restore or share profiles.

## How to set up the Android app in your development environment

### Application Flavors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,12 @@ private void createCheckboxList() {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
finish();rea
}else if (item.getItemId() == R.id.compass_help_icon) {

Comment on lines 161 to +164
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Typo causing compile error

Remove the extra "rea" after finish() to fix the syntax error.

Suggested change
if (item.getItemId() == android.R.id.home) {
finish();
finish();rea
}else if (item.getItemId() == R.id.compass_help_icon) {
if (item.getItemId() == android.R.id.home) {
finish();
}else if (item.getItemId() == R.id.compass_help_icon) {

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://your-documentation-link.com"));
startActivity(browserIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
Expand Down
25 changes: 25 additions & 0 deletions app/src/main/java/io/pslab/activity/RoboticArmActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,20 @@ protected void onCreate(Bundle savedInstanceState) {
seekArc1.setOnSeekArcChangeListener(new SeekArc.OnSeekArcChangeListener() {
@Override
public void onProgressChanged(SeekArc seekArc, int i, boolean b) {
int angle;
if (editEnter) {
angle = degree;
degreeText1.setText(String.valueOf(degree));
editEnter = false;
} else {
angle = (int) (i * 3.6);
degreeText1.setText(String.valueOf((int) (i * 3.6)));
}
degreeText1.setCursorVisible(false);

if (scienceLab != null && scienceLab.isConnected()) {
scienceLab.servoWrite(0, angle);
}
}

@Override
Expand All @@ -248,13 +255,19 @@ public void onStopTrackingTouch(SeekArc seekArc) {
seekArc2.setOnSeekArcChangeListener(new SeekArc.OnSeekArcChangeListener() {
@Override
public void onProgressChanged(SeekArc seekArc, int i, boolean b) {
int angle;
if (editEnter) {
angle = degree;
degreeText2.setText(String.valueOf(degree));
editEnter = false;
} else {
angle = (int) (i * 3.6);
degreeText2.setText(String.valueOf((int) (i * 3.6)));
}
degreeText2.setCursorVisible(false);
if (scienceLab != null && scienceLab.isConnected()) {
scienceLab.servoWrite(1, angle);
}
}

@Override
Expand All @@ -271,13 +284,19 @@ public void onStopTrackingTouch(SeekArc seekArc) {
seekArc3.setOnSeekArcChangeListener(new SeekArc.OnSeekArcChangeListener() {
@Override
public void onProgressChanged(SeekArc seekArc, int i, boolean b) {
int angle;
if (editEnter) {
angle = degree;
degreeText3.setText(String.valueOf(degree));
editEnter = false;
} else {
angle = (int) (i * 3.6);
degreeText3.setText(String.valueOf((int) (i * 3.6)));
}
degreeText3.setCursorVisible(false);
if (scienceLab != null && scienceLab.isConnected()) {
scienceLab.servoWrite(2, angle);
}
}

@Override
Expand All @@ -294,13 +313,19 @@ public void onStopTrackingTouch(SeekArc seekArc) {
seekArc4.setOnSeekArcChangeListener(new SeekArc.OnSeekArcChangeListener() {
@Override
public void onProgressChanged(SeekArc seekArc, int i, boolean b) {
int angle;
if (editEnter) {
angle = degree;
degreeText4.setText(String.valueOf(degree));
editEnter = false;
} else {
angle = (int) (i * 3.6);
degreeText4.setText(String.valueOf((int) (i * 3.6)));
}
degreeText4.setCursorVisible(false);
if (scienceLab != null && scienceLab.isConnected()) {
scienceLab.servoWrite(3, angle);
}
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/io/pslab/activity/SensorActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
sensorAddr.put(0x77, "BMP180");
sensorAddr.put(0x5A, "MLX90614");
sensorAddr.put(0x1E, "HMC5883L");
sensorAddr.put(0x68, "MPU6050");
sensorAddr.put(0x69, "MPU6050");
sensorAddr.put(0x40, "SHT21");
sensorAddr.put(0x39, "TSL2561");
sensorAddr.put(0x69, "MPU925x");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
sensorAddress.put(0x77, "BMP180");
sensorAddress.put(0x5A, "MLX90614");
sensorAddress.put(0x1E, "HMC5883L");
sensorAddress.put(0x68, "MPU6050");
sensorAddress.put(0x69, "MPU6050");
sensorAddress.put(0x40, "SHT21");
sensorAddress.put(0x39, "TSL2561");
}
Expand Down
31 changes: 28 additions & 3 deletions app/src/main/java/io/pslab/activity/SettingsActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ protected void onCreate(Bundle savedInstanceState) {
actionBar.setTitle(title);
}

Button myButton = findViewById(R.id.myButton);
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(CompassActivity.this, "Button clicked!", Toast.LENGTH_SHORT).show();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Incorrect context in Toast call

Use SettingsActivity.this or simply this as the context to avoid confusion and potential memory leaks.

}
});

Fragment fragment;
switch (title) {
case PSLabSensor.LUXMETER_CONFIGURATIONS:
Expand Down Expand Up @@ -95,12 +103,29 @@ protected void onCreate(Bundle savedInstanceState) {
getSupportFragmentManager().beginTransaction().add(R.id.content, fragment).commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_compass_help_menu, menu);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Menu resource seems misnamed

The use of 'activity_compass_help_menu' in SettingsActivity suggests a copy-paste error. Please use a menu resource appropriate for settings.

return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
int id = item.getItemId();

if (id == android.R.id.home) {
finish();
return true;
} else if (id == R.id.compass_record_data) {

Toast.makeText(this, "Recording current compass data...", Toast.LENGTH_SHORT).show();
return true;
} else if (id == R.id.compass_help_icon) {

Toast.makeText(this, "Opening compass help...", Toast.LENGTH_SHORT).show();
return true;
}

return super.onOptionsItemSelected(item);
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/io/pslab/communication/SensorList.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public SensorList() {
sensorList.put(0x5A, new String[]{"MLX90614 PIR temperature"});
sensorList.put(0x1E, new String[]{"HMC5883L magnetometer", "LSM303 magnetometer"});
sensorList.put(0x77, new String[]{"BMP180/GY-68 altimeter", "MS5607", "MS5611"});
sensorList.put(0x68, new String[]{"MPU-6050/GY-521 accel+gyro+temp", "ITG3200", "DS1307", "DS3231"});
sensorList.put(0x69, new String[]{"MPU-6050/GY-521 accel+gyro+temp", "ITG3200", "DS1307", "DS3231"});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Conflicting sensorList key

0x69 is assigned to two different sensor sets, causing one to overwrite the other. Please ensure each key is unique or combine the sensor sets as needed.

sensorList.put(0x69, new String[]{"ITG3200"});
sensorList.put(0x76, new String[]{"MS5607", "MS5611"});
sensorList.put(0x6B, new String[]{"LSM9DSO gyro"});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class MPU6050 {
private int GR = 3;
private int NUMPLOTS = 7;
public String[] PLOTNAMES = {"Ax", "Ay", "Az,'Temp", "Gx", "Gy", "Gz"};
private int ADDRESS = 0x68;
private int ADDRESS = 0x69;
private String name = "Accel/gyro";
private ArrayList<KalmanFilter> K = new ArrayList<>(); //K is the list of KalmanFilter object
private I2C i2c;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class MPU925x {
private int GR = 3;
private int NUMPLOTS = 7;
public String[] PLOTNAMES = new String[]{"Ax", "Ay", "Az", "Temp", "Gx", "Gy", "Gz"};
private int ADDRESS = 0x68;
private int ADDRESS = 0x69;
private int AK8963_ADDRESS = 0x0C;
private int AK8963_CNTL = 0x0A;
public String name = "Accel/gyro";
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/io/pslab/fragment/AccelerometerDataFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,9 @@ private void writeLogToFile(long timestamp, float readingX, float readingY, floa
accelerometerSensor.writeHeaderToFile = true;
}
}
public LineChart getChart() {
return chart;
}

private void visualizeData() {
for (int i = 0; i < accelerometerViewFragments.size(); i++) {
Expand All @@ -435,7 +438,16 @@ private void visualizeData() {
LineData data = new LineData(dataSet);

fragment.setChartData(data);

fragment.setYaxis(highLimit);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Fixed Y-axis conflicting with auto-scaling

Remove setYaxis(highLimit) to allow auto-scaling to function as intended.

// ✅ Auto-scaling Y-axis
LineChart chart = fragment.getChart(); // Assuming you have this getter method
chart.setAutoScaleMinMaxEnabled(true);
chart.getAxisLeft().resetAxisMaximum();
chart.getAxisLeft().resetAxisMinimum();

chart.notifyDataSetChanged();
chart.invalidate();
}
}
Long currentTime = System.currentTimeMillis();
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/java/io/pslab/fragment/BaroMeterDataFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,6 @@ private enum BARO_SENSOR {INBUILT_SENSOR, BMP180_SENSOR}
private ArrayList<Entry> altitudeEntries;
private ArrayList<BaroData> recordedBaroArray;
private BaroData sensorData;
private float currentMin = 2;
private float currentMax = 0.5f;
private YAxis y;
private YAxis y2;
private Unbinder unbinder;
Expand Down Expand Up @@ -166,12 +164,18 @@ public void onResume() {
updateGraphs();
sum = 0;
count = 0;
currentMin = 2;
currentMax = 0.5f;
// REMOVE these fixed axis values to allow auto-scaling
// currentMin = 2;
// currentMax = 0.5f;
pressureEntries.clear();
altitudeEntries.clear();
mChart.clear();
mChart.invalidate();
// Auto-scaling: reset min/max if using MPAndroidChart
mChart.getAxisLeft().resetAxisMinimum();
mChart.getAxisLeft().resetAxisMaximum();
mChart.getAxisRight().resetAxisMinimum();
mChart.getAxisRight().resetAxisMaximum();
initiateBaroSensor(sensorType);
} else if (returningFromPause) {
updateGraphs();
Expand Down
15 changes: 14 additions & 1 deletion app/src/main/java/io/pslab/fragment/GyroscopeDataFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ private void writeLogToFile(long timestamp, float readingX, float readingY, floa
gyroSensor.writeHeaderToFile = true;
}
}
public LineChart getChart() {
return chart; // Make sure your LineChart variable is named 'chart'
}

private void visualizeData() {
for (int i = 0; i < gyroscopeViewFragments.size(); i++) {
Expand All @@ -441,7 +444,17 @@ private void visualizeData() {
LineData data = new LineData(dataSet);

fragment.setChartData(data);
fragment.setYaxis(highLimit);
// REMOVE this line as it is forcing fixed Y-axis:
// fragment.setYaxis(highLimit);

// NEW: Enable auto-scaling
LineChart chart = fragment.getChart();
chart.setAutoScaleMinMaxEnabled(true);
chart.getAxisLeft().resetAxisMaximum();
chart.getAxisLeft().resetAxisMinimum();

chart.notifyDataSetChanged();
chart.invalidate();
}
}
Long currentTime = System.currentTimeMillis();
Expand Down
13 changes: 9 additions & 4 deletions app/src/main/java/io/pslab/fragment/LuxMeterDataFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ private enum LUX_SENSOR {INBUILT_SENSOR, BH1750_SENSOR, TSL2561_SENSOR}
private ArrayList<Entry> entries;
private ArrayList<LuxData> recordedLuxArray;
private LuxData sensorData;
private float currentMin = 10000;
private float currentMax = 0;
private YAxis y;
private Unbinder unbinder;
private long previousTimeElapsed = (System.currentTimeMillis() - startTime) / updatePeriod;
Expand Down Expand Up @@ -162,11 +160,18 @@ public void onResume() {
updateGraphs();
sum = 0;
count = 0;
currentMin = 10000;
currentMax = 0;
// REMOVE these fixed axis values to allow auto-scaling
// currentMin = 10000;
// currentMax = 0;
entries.clear();
mChart.clear();
mChart.invalidate();
// Auto-scaling: reset min/max if using MPAndroidChart
mChart.getAxisLeft().resetAxisMinimum();
mChart.getAxisLeft().resetAxisMaximum();
mChart.getAxisRight().resetAxisMinimum();
mChart.getAxisRight().resetAxisMaximum();
initiateBaroSensor(sensorType);
initiateLuxSensor(sensorType);
} else if (returningFromPause) {
updateGraphs();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ private enum THERMOMETER_SENSOR {INBUILT_SENSOR, SHT21_SENSOR}
private ArrayList<Entry> entries;
private ArrayList<ThermometerData> recordedThermoArray;
private ThermometerData sensorData;
private float currentMin = 125;
private float currentMax = -40;
private YAxis y;
private Unbinder unbinder;
private long previousTimeElapsed = (System.currentTimeMillis() - startTime) / updatePeriod;
Expand Down Expand Up @@ -166,6 +164,13 @@ public void onResume() {
entries.clear();
mChart.clear();
mChart.invalidate();
// Auto-scaling: reset min/max if using MPAndroidChart
mChart.getAxisLeft().resetAxisMinimum();
mChart.getAxisLeft().resetAxisMaximum();
mChart.getAxisRight().resetAxisMinimum();
mChart.getAxisRight().resetAxisMaximum();
initiateBaroSensor(sensorType);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Erroneous initialization of non-thermometer sensors

Remove the initialization of Baro and Lux sensors from ThermometerDataFragment to ensure only the thermometer sensor is started.

initiateLuxSensor(sensorType);
initiateThermoSensor(sensorType);
} else if (returningFromPause) {
updateGraphs();
Expand Down
Loading
Loading