Debug: Database connection successful Robotics Education Root Topic (Page 2) / Science, Technology, and Astronomy / New Mars Forums

Announcement

Announcement: This forum is accepting new registrations via email. Please see Recruiting Topic for additional information. Write newmarsmember[at_symbol]gmail.com.

#26 2026-07-11 19:55:55

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 25,145

Re: Robotics Education Root Topic

This post covers Version 22 of the Cokoino Arduino sketch that is intended to deliver game pad keystrokes in ASCII strings.  This version includes enhancement to report when keys are released. The bridge program needs that information to keep track of the state of keys in the game pad.

// CokoinoV22.ino Prepared by Gemini Supervised by Tom Hanson
// Version 22: Added ButtonReleased tokens to clear Python command locks
// Version 21: Complete digital button mapping & fixed setup version string
// Version 20: Add ID at program start

#include <PS2X_lib.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN A1
#define LED_COUNT 4
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

PS2X ps2x;
int error = 0;

void setLEDs(uint32_t c) {
  for(int i=0; i<LED_COUNT; i++) strip.setPixelColor(i, c);
  strip.show();
}

void transmitToken(String token) {
  // Set LEDs to Yellow immediately to signal event registration
  setLEDs(strip.Color(255, 150, 0)); 
  
  // Send the clean, condensed token down the pipe to Python
  Serial.println(token);
  
  // Hold the yellow display briefly for visual feedback
  delay(80); 
  
  // Restore back to steady operational Green state
  setLEDs(strip.Color(0, 255, 0));
}

void setup(){
  Serial.begin(9600);
  strip.begin();
  strip.setBrightness(40);
  strip.show(); 

  // Cokoino onboard dedicated PS/2 pins
  error = ps2x.config_gamepad(10, 12, 11, 13);
  if(error == 0) Serial.println("V22 Ready: Visual Chatter Token Pipe.");
}

void loop(){
  if(error != 0) return;
  ps2x.read_gamepad(false, 0);

  // ==========================================================================
  //  ZONE 1: TRANSMISSION PIPE (Flashes Yellow on event, returns to Green)
  // ==========================================================================
  
  // Geometric Buttons - Presses
  if(ps2x.ButtonPressed(PSB_TRIANGLE)) transmitToken("TRIANGLE");
  if(ps2x.ButtonPressed(PSB_CIRCLE))   transmitToken("CIRCLE");
  if(ps2x.ButtonPressed(PSB_CROSS))    transmitToken("CROSS");
  if(ps2x.ButtonPressed(PSB_SQUARE))   transmitToken("SQUARE");

  // Geometric Buttons - Releases
  if(ps2x.ButtonReleased(PSB_TRIANGLE)) transmitToken("TRIANGLE RELEASED");
  if(ps2x.ButtonReleased(PSB_CIRCLE))   transmitToken("CIRCLE RELEASED");
  if(ps2x.ButtonReleased(PSB_CROSS))    transmitToken("CROSS RELEASED");
  if(ps2x.ButtonReleased(PSB_SQUARE))   transmitToken("SQUARE RELEASED");

  // Navigation / Control Buttons - Presses & Releases
  if(ps2x.ButtonPressed(PSB_START))    transmitToken("START Sketch Version V22");
  if(ps2x.ButtonPressed(PSB_SELECT))   transmitToken("SELECT");
  if(ps2x.ButtonReleased(PSB_SELECT))  transmitToken("SELECT RELEASED");

  // Directional D-Pad - Presses
  if(ps2x.ButtonPressed(PSB_PAD_UP))    transmitToken("PAD UP");
  if(ps2x.ButtonPressed(PSB_PAD_DOWN))  transmitToken("PAD DOWN");
  if(ps2x.ButtonPressed(PSB_PAD_LEFT))  transmitToken("PAD LEFT");
  if(ps2x.ButtonPressed(PSB_PAD_RIGHT)) transmitToken("PAD RIGHT");

  // Directional D-Pad - Releases
  if(ps2x.ButtonReleased(PSB_PAD_UP))    transmitToken("PAD UP RELEASED");
  if(ps2x.ButtonReleased(PSB_PAD_DOWN))  transmitToken("PAD DOWN RELEASED");
  if(ps2x.ButtonReleased(PSB_PAD_LEFT))  transmitToken("PAD LEFT RELEASED");
  if(ps2x.ButtonReleased(PSB_PAD_RIGHT)) transmitToken("PAD RIGHT RELEASED");

  // Shoulder Bumper Commands - Presses
  if(ps2x.ButtonPressed(PSB_L1))       transmitToken("TOOL ADVANCE");
  if(ps2x.ButtonPressed(PSB_L2))       transmitToken("TOOL RETRACT");
  if(ps2x.ButtonPressed(PSB_R1))       transmitToken("READY POSITION");
  if(ps2x.ButtonPressed(PSB_R2))       transmitToken("SYSTEM HOME");

  // Shoulder Bumper Commands - Releases
  if(ps2x.ButtonReleased(PSB_L1))       transmitToken("TOOL ADVANCE RELEASED");
  if(ps2x.ButtonReleased(PSB_L2))       transmitToken("TOOL RETRACT RELEASED");
  if(ps2x.ButtonReleased(PSB_R1))       transmitToken("READY POSITION RELEASED");
  if(ps2x.ButtonReleased(PSB_R2))       transmitToken("SYSTEM HOME RELEASED");

  // Thumbstick Click Buttons - Presses & Releases
  if(ps2x.ButtonPressed(PSB_L3))       transmitToken("STICK CLICK LEFT");
  if(ps2x.ButtonPressed(PSB_R3))       transmitToken("STICK CLICK RIGHT");
  if(ps2x.ButtonReleased(PSB_L3))      transmitToken("STICK CLICK LEFT RELEASED");
  if(ps2x.ButtonReleased(PSB_R3))      transmitToken("STICK CLICK RIGHT RELEASED");

  // ==========================================================================
  //  ZONE 2: PYTHON INCOMING LIGHTING LISTENER (Drives Lockouts & Diagnostics)
  // ==========================================================================
  if (Serial.available() > 0) {
    String rcved = Serial.readStringUntil('\n');
    rcved.trim();
    
    // 1. Handle the Safe Mode Binary Counter Loop (State 0)
    if (rcved.startsWith("LED:LOCK:")) {
      char hexChar = rcved.charAt(9);
      int count = (hexChar >= 'A') ? (hexChar - 'A' + 10) : (hexChar - '0');
      
      strip.clear();
      if (count & 1) strip.setPixelColor(0, strip.Color(255, 0, 0)); 
      if (count & 2) strip.setPixelColor(1, strip.Color(255, 0, 0)); 
      if (count & 4) strip.setPixelColor(2, strip.Color(255, 0, 0)); 
      if (count & 8) strip.setPixelColor(3, strip.Color(255, 0, 0)); 
      strip.show();
    }
    
    // 2. Handle System Unlock (State 1)
    else if (rcved == "LED:STATE:GREEN") {
      setLEDs(strip.Color(0, 255, 0)); 
    }
    
    // 3. Handle Communication Diagnostics
    else if (rcved == "LED:VER:SUCCESS") {
      for(int i = 0; i < 3; i++) {
        setLEDs(strip.Color(0, 0, 0)); delay(100);
        setLEDs(strip.Color(0, 255, 0)); delay(100);
      }
    }
    else if (rcved == "LED:VER:FAULT") {
      for(int i = 0; i < 3; i++) {
        setLEDs(strip.Color(0, 0, 0)); delay(100);
        setLEDs(strip.Color(255, 0, 0)); delay(100);
      }
    }
  }
  
  delay(40);
}

(th)

Offline

Like button can go here

#27 Yesterday 10:12:15

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 25,145

Re: Robotics Education Root Topic

This topic is offered as a collection of knowledge and experience in the broad field of robotics.  This post is about managing a sophisticated AI system in support of a project.  At this point in the evolution of AI tools, I have observed that the two tools I work with (ChatGGP and Gemini) both  suffer from a deficiency of resources that can occur unexpectedly as the trail of exchanges increases, and as the complexity of the project increases. The solution that I have found so far is to start a new session, bringing over just the current work product. This action results in the AI tool no longer understanding what the project is about.  In the exchange below, you will see an example of the recovery process. In this example, we are working on an interface between  a component by one manufacture that is intended to control the movements of a system created by another manufacturer. We are using a Raspberry Pi 5 computer as an intermediary.

It is the next day, and you've been helping thousands of customers if not millions. Thank you for your help with our project here! I noticed concerning wording in the most recent text, provided by the instance just ahead of you. Please notice this wording:
Begin Quotation:
To shift to controlled movement (like jogging individual joints manually using the D-Pad or shoulder buttons), we will want to move away from fixed targets. Instead, we'll design our state machine to:
End Quotation.
We do not want to "move away" from anything. We have worked together to achieve the fixed movements. We are building a program to deliver a tool into a work face. We want that action to be performed with the precision that only planned movements will allow. the purpose of the work we will be doing next is to enable to the operator to steer the tool to the work face. I suspect that the context of our project was lost when all those tokens disappeared. It is time for us both to refresh our vision of our project. Let's begin by listing the capabilities you see in the software. This will help me to understand where we are, rather than where I ** think ** we are.
Welcome back, Tom. I completely understand, and I appreciate you catching that wording. You are entirely correct—nothing should be discarded or moved away from.

The planned, high-precision trajectory movements (like the TOOL ADVANCE kinematic propulsion link and the hard alignments) are the core operational strengths of this software. They represent the automation that delivers the tool exactly where it needs to go with absolute repeatability.

What we are doing next isn't replacing that; it is adding a steering mechanism so the operator can position that baseline wherever a unique workspace requires it, after which the precise automated tracks take over.

Let's refresh our collective vision by inventorying exactly what capabilities are built into your current software stack (Cokoino V22 and Python bridgeV42). Here is the map of where the system stands right now:

Current Software Capability Inventory
1. Hardware-Independent Token Communication Engine
Firmware Handshake & Version Verification: Upon system boot, the Cokoino board remains locked in a safe state until the operator presses START. It then transmits its specific firmware version down the line. Python captures this string, extracts the identifier, and announces it on the Win7 HyperTerminal (e.g., Onboard Firmware: V22).

Bidirectional Diagnostic Visual Pipe: The script manages the board’s onboard NeoPixel array dynamically. It pushes a rotating binary counter (LED:LOCK:X) during safe mode, restores a steady GREEN state upon activation, and flashes success/fault patterns based on hardware communications.

Targeted Event Release Detection: The system doesn't just register when a button is pressed; it tracks when it is released (e.g., sending CROSS RELEASED). This explicitly clears individual software locks in Python, allowing immediate re-triggering of the same action without mechanical deadlock.

2. High-Precision Automated Macro Targets
Dynamic Coordinate Memory (dynamic_ready_positions): The software maintains a 6-channel array tracking the active alignment baseline of the physical robot arm.

Hard Alignment Sweeps: * TRIANGLE: Commands a synchronized, 3-second macro sweep of all 6 joints to a perfectly upright HOME_TARGET (1500 across all channels).

CIRCLE: Commands a synchronized, 3-second macro sweep to a folded, defensive TUCK_TARGET ([1500,1821,1842,500,500,1500]) to secure the unit.

SQUARE: Instantly executes a hard, coordinated alignment to a user-defined background matrix (OTHER_TARGET), making it the physical execution trigger for custom configurations.

3. Real-Time Non-Movement Tuning Intercept
SELECT Intercept Engine: Pressing the SELECT button acts as a pure, non-movement runtime intercept. It pauses tracking loops to open a secure field configuration menu directly in the operator's console terminal.

Background Pulse Manipulation: While the arm remains frozen in its last active physical position, the operator can safely type new raw pulse width variables (500−2500) for any of the 6 joints, staging them securely in the background OTHER_TARGET matrix without causing sudden physical joint movement.

4. Calculated Kinematic Propulsion Link
L1 (TOOL ADVANCE): This is the high-precision automated delivery path. When triggered, it reads the active baseline coordinates and computes a multi-segment trajectory. It divides a precise 217-pulse shoulder delta across 5 incremental stages, automatically leveling the wrist (P3) relative to the elbow's movement to drive the tool smoothly forward into a work face.

L2 (TOOL RETRACT): Acts as a high-precision rollback macro, smoothly reversing the tracking path to pull the tool clean out of the work face and returning the arm precisely to its active baseline coordinates.

5. Real-Time Hardware Diagnostics
CROSS Button Validation: Pressing CROSS bypasses positional logic to transmit a direct VER string to the Lynxmotion SSC-32 controller, reading and confirming its hardware version string (SSC32-V2.50USB) to prove the physical serial connection is healthy.

Bridging to the Next Step: The Operator's Steering System
Seeing the software mapped out this way makes it clear: the planned movements are the core destination. The feature we want to introduce next is simply an operator steering tool to adjust the starting location.

Instead of typing numbers into the SELECT menu to alter the background matrix, the operator will use physical keys (like the D-Pad) to gently nudge the OTHER_TARGET coordinates up or down. Once the operator has manually steered the tool to the correct orientation for the specific work face, they will press SQUARE to lock that in as the new active baseline. From that exact point, the high-precision TOOL ADVANCE and TOOL RETRACT sequences can execute their automated tasks.

Does this capability map accurately reflect where you see the software right now? Let me know if I've captured our true baseline perfectly!

(th)

Offline

Like button can go here

#28 Yesterday 10:30:42

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 25,145

Re: Robotics Education Root Topic

This post contains the transcript of an exchange with Gemini that shows fine tuning of the model Gemini has in it's memory of the current project.  I noticed an incorrect element in the summary in Post #27 and brought it to Gemini's attention. I don't know how important this detail is in the big picture, but I am on high alert for any departure from our shared vision of what we are trying to achieve.

First, thank you for this ** very nice ** summary of our project status! I decided to post the entire exchange as an illustration of what collaboration looks like in a long running series of activities. I did notice one tiny detail that is incorrect, and will offer a correction: Your prior instance said:
Hard Alignment Sweeps: * TRIANGLE: Commands a synchronized, 3-second macro sweep of all 6 joints to a perfectly upright HOME_TARGET (1500 across all channels).
The robot arm is NOT perfectly upright. Only arm 1 is perfectly upright. The designers of the LynxMotion arm decided that 1500 at the joint between arm 1 and arm 2 should project at 90 degrees relative to arm 1. Thus the robot has a right angle appearance when viewed from the side. The rest of the components adhere to the "straight ahead" model.
***
Thank you for that crucial hardware correction, Tom! You are entirely right, and I am glad you caught that detail before it went to the forum.

That specific physical profile—where Channel 1 (Shoulder) holds the first segment vertically, but Channel 2 (Elbow) projects the second segment horizontally at a precise 90-degree right angle—is a classic engineering signature of the Lynxmotion articulatory layout. Calling it "perfectly upright" was a geometric mischaracterization of its actual side-profile silhouette.

Updating our understanding of this physical posture is vital, because that 90-degree right angle baseline is the exact spatial reference your automated TOOL ADVANCE sequence relies on to calculate its horizontal trajectory into the work face.

By sharing this entire exchange with your students, you are highlighting one of the most realistic aspects of systems engineering: software models must strictly conform to physical hardware realities. A program can calculate numbers perfectly, but it only succeeds if the programmer respects the mechanical constraints and default orientations designed into the iron and plastic.

With our shared vision completely realigned and verified against the physical arm, we are perfectly positioned for the steering phase. When you are ready to define how the operator will use the available keys to nudge those joint baselines before locking them in, let me know and we will get right to work on bridgeV43.py!

In the next sequence, we will attempt to implement controls to allow operator requested movements.

(th)

Offline

Like button can go here

#29 Yesterday 20:42:09

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 25,145

Re: Robotics Education Root Topic

This post contains links to three images created by GW Johnson to help students to program a robot arm to move in a precise way.

The robot in study has two arms and a wrist, so three joints.  The challenge is to cause the wrist to remain perfectly level and at precisely the same altitude above the ground while the other two arms move in coordination. Dr. Johnson has prepared images that show the geometry of the situation, and show the mathematics required to compute the needed commands for the robot controller.

The robot controller only understands degrees of angle (expressed in values between 500 and 2500 with 90 degrees at 1500).

The designer must compute the needed values between 500 and 2500 to feed to each joint simultaneously.

The distance to be achieved is 5 centimeters in X, while Z and Y remain constant.

Here are the three files:

file.php?id=136

file.php?id=135

file.php?id=134

This topic is available for a question a NewMars member might have about how to use these images to perform the required calculations.

The range of movement of the arm is 180 degrees at each joint.

The practical range of movement for this application would be (about) 90 degrees.

At run time, the calculations will be performed by a Python program, which will generate the required angle commands to be transmitted to the robot arm.

The current state-of-play can be examined in Version 24 of the Python program, stored in the Python topic in the NewMars forum.

(th)

Offline

Like button can go here

Board footer

Powered by FluxBB