Jump to content

More Arduino help - now completely confused!


blinky

Recommended Posts

So you will have seen from my other posts that I am trying to add the temperature reading to a moonlight compatible Arduino focuser sketch.  After much question asking I thought I had it sussed but tonight had more problems.  I have now got this far...

If I upload the basis DS1820B Test Sketch I get correct temperature readings:

/********************************************************************/
// First we include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>
/********************************************************************/
// Data wire is plugged into pin 2 on the Arduino 
#define ONE_WIRE_BUS 2 
/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices  
// (not just Maxim/Dallas temperature ICs) 
OneWire oneWire(ONE_WIRE_BUS); 
/********************************************************************/
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
/********************************************************************/ 
void setup(void) 
{ 
 // start serial port 
 Serial.begin(9600); 
 Serial.println("Dallas Temperature IC Control Library Demo"); 
 // Start up the library 
 sensors.begin(); 
} 
void loop(void) 
{ 
 // call sensors.requestTemperatures() to issue a global temperature 
 // request to all devices on the bus 
/********************************************************************/
 Serial.print(" Requesting temperatures..."); 
 sensors.requestTemperatures(); // Send the command to get temperature readings 
 Serial.println("DONE"); 
/********************************************************************/
 Serial.print("Temperature is: "); 
 Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?  
   // You can have more than one DS18B20 on the same bus.  
   // 0 refers to the first IC on the wire 
   delay(1000); 
  

 

Output on the serial monitor is this:

Requesting temperatures...DONE
Temperature is: 18.69

 

 

IIf I now upload the actual sketch and get it to output the same information when I enter the GT# command I get 85.00 on the serial line and cannot figure out why!  The sketch for this is below and I have marked the GT command in Bold and Underlined it:

 

 

// Moonlite-compatible stepper controller
//
// Uses AccelStepper (http://www.airspayce.com/mikem/arduino/AccelStepper/)
// Uses AFMotor and the Adafruit v1.2 Motor Shield https://learn.adafruit.com/adafruit-motor-shield
//
// Requires a 10uf - 100uf capacitor between RESET and GND on the motor shield; this prevents the
// Arduino from resetting on connect (via DTR going low).  Without the capacitor, this sketch works
// with the stand-alone Moonlite control program (non-ASCOM) but the ASCOM driver does not detect it.
// Adding the capacitor allows the Arduino to respond quickly enough to the ASCOM driver probe
//
// orly.andico@gmail.com, 13 April 2014


#include <AccelStepper.h>
#include <AFMotor.h>
#include <OneWire.h> 
#include <DallasTemperature.h>
#include <Math.h>

#define ONE_WIRE_BUS 2 
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);


// maximum speed is 160pps which should be OK for most
// tin can steppers
#define MAXSPEED 100
#define SPEEDMULT 3

AF_Stepper motor1(300, 1);

void forwardstep() {  
  motor1.onestep(BACKWARD, DOUBLE);
}

void backwardstep() {  
  motor1.onestep(FORWARD, DOUBLE);
}

AccelStepper stepper(forwardstep, backwardstep);

#define MAXCOMMAND 8

char inChar;
char cmd[MAXCOMMAND];
char param[MAXCOMMAND];
char line[MAXCOMMAND];
long pos;
int isRunning = 0;
int speed = 32;
int eoc = 0;
int idx = 0;
long millisLastMove = 0;

void setup()
{  
  Serial.begin(9600);

  // we ignore the Moonlite speed setting because Accelstepper implements
  // ramping, making variable speeds un-necessary
  stepper.setSpeed(MAXSPEED);
  stepper.setMaxSpeed(MAXSPEED);
  stepper.setAcceleration(10);
  stepper.enableOutputs();
  memset(line, 0, MAXCOMMAND);
  millisLastMove = millis();
  
  sensors.begin(); 
}

void loop(){
  // run the stepper if there's no pending command and if there are pending movements
  if (!Serial.available())
  {
    if (isRunning) {
      stepper.run();
      millisLastMove = millis();
    } 
    else {
      // reported on INDI forum that some steppers "stutter" if disableOutputs is done repeatedly
      // over a short interval; hence we only disable the outputs and release the motor some seconds
      // after movement has stopped
      if ((millis() - millisLastMove) > 15000) {
        stepper.disableOutputs();
        motor1.release();
      }
    }

    if (stepper.distanceToGo() == 0) {
      stepper.run();
      isRunning = 0;
    }
  } 
  else {

    // read the command until the terminating # character
    while (Serial.available() && !eoc) {
      inChar = Serial.read();
      if (inChar != '#' && inChar != ':') {
        line[idx++] = inChar;
        if (idx >= MAXCOMMAND) {
          idx = MAXCOMMAND - 1;
        }
      } 
      else {
        if (inChar == '#') {
          eoc = 1;
        }
      }
    }
  } // end if (!Serial.available())

  // process the command we got
  if (eoc) {
    memset(cmd, 0, MAXCOMMAND);
    memset(param, 0, MAXCOMMAND);

    int len = strlen(line);
    if (len >= 2) {
      strncpy(cmd, line, 2);
    }

    if (len > 2) {
      strncpy(param, line + 2, len - 2);
    }

    memset(line, 0, MAXCOMMAND);
    eoc = 0;
    idx = 0;

    // the stand-alone program sends :C# :GB# on startup
    // :C# is a temperature conversion, doesn't require any response

    // LED backlight value, always return "00"
    if (!strcasecmp(cmd, "GB")) {
      Serial.print("00#");
    }

    // home the motor, hard-coded, ignore parameters since we only have one motor
    if (!strcasecmp(cmd, "PH")) { 
      stepper.setCurrentPosition(8000);
      stepper.moveTo(0);
      isRunning = 1;
    }

    // firmware value, always return "10"
    if (!strcasecmp(cmd, "GV")) {
      Serial.print("10#");
    }

    // get the current motor position
    if (!strcasecmp(cmd, "GP")) {
      pos = stepper.currentPosition();
      char tempString[6];
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }

    // get the new motor position (target)
    if (!strcasecmp(cmd, "GN")) {
      pos = stepper.targetPosition();
      char tempString[6];
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }

    // get the current temperature, hard-coded
    if (!strcasecmp(cmd, "GT")) {
      //Serial.print("20#");      
    Serial.print(sensors.getTempCByIndex(0)); 

   
      
    }

    // get the temperature coefficient, hard-coded
    if (!strcasecmp(cmd, "GC")) {
      Serial.print("02#");
    }

    // get the current motor speed, only values of 02, 04, 08, 10, 20
    if (!strcasecmp(cmd, "GD")) {
      char tempString[6];
      sprintf(tempString, "%02X", speed);
      Serial.print(tempString);
      Serial.print("#");
    }

    // set speed, only acceptable values are 02, 04, 08, 10, 20
    if (!strcasecmp(cmd, "SD")) {
      speed = hexstr2long(param);

      // we ignore the Moonlite speed setting because Accelstepper implements
      // ramping, making variable speeds un-necessary

      // stepper.setSpeed(speed * SPEEDMULT);
      // stepper.setMaxSpeed(speed * SPEEDMULT);
      stepper.setSpeed(MAXSPEED);
      stepper.setMaxSpeed(MAXSPEED);
    }

    // whether half-step is enabled or not, always return "00"
    if (!strcasecmp(cmd, "GH")) {
      Serial.print("00#");
    }

    // motor is moving - 01 if moving, 00 otherwise
    if (!strcasecmp(cmd, "GI")) {
      if (abs(stepper.distanceToGo()) > 0) {
        Serial.print("01#");
      } 
      else {
        Serial.print("00#");
      }
    }

    // set current motor position
    if (!strcasecmp(cmd, "SP")) {
      pos = hexstr2long(param);
      stepper.setCurrentPosition(pos);
    }

    // set new motor position
    if (!strcasecmp(cmd, "SN")) {
      pos = hexstr2long(param);
      stepper.moveTo(pos);
    }


    // initiate a move
    if (!strcasecmp(cmd, "FG")) {
      isRunning = 1;
      stepper.enableOutputs();
    }

    // stop a move
    if (!strcasecmp(cmd, "FQ")) {
      isRunning = 0;
      stepper.moveTo(stepper.currentPosition());
      stepper.run();
    }
  }
} // end loop

long hexstr2long(char *line) {
  long ret = 0;

  ret = strtol(line, NULL, 16);
  return (ret);
}

Link to comment
Share on other sites

Ive only quickly scanned your code, but I don't think you are reading it before you print it. Ive not been following your previous work on this so don't really have a full understanding of it, so apologies if you've done it somewhere and I've missed it.

Try adding the following line in your IF statement before you print the value:

sensors.requestTemperatures();

 

Link to comment
Share on other sites

Just to clarify, try the following code....

 // get the current temperature, hard-coded
    if (!strcasecmp(cmd, "GT")) {
      //Serial.print("20#");      

sensors.requestTemperatures();
    Serial.print(sensors.getTempCByIndex(0)); 

Link to comment
Share on other sites

Try moving your temperature sensor to a different pin. See of if the problem moves with it, or goes away.

Otherwise, I think you're going to have to fall back on the tried and tested debugging method of removing code from your program until it starts to work. Then try to figure out why that (almost always innocuous) last piece of code stops a perfectly well written program from working!

Link to comment
Share on other sites

7 hours ago, davyludo said:

Just to clarify, try the following code....

 // get the current temperature, hard-coded
    if (!strcasecmp(cmd, "GT")) {
      //Serial.print("20#");      

sensors.requestTemperatures();
    Serial.print(sensors.getTempCByIndex(0)); 

Thats all it was!  I can now output a hex value, I divide by half as has been suggested and round it to allow it to read half degree increments as INT and can now see on the serial monitor 08#  But..... The moonlight app crashes, INPUT STRING WAS NOT IN A CORRECT FORMAT

Link to comment
Share on other sites

It looks like the moonlight app expects the numerical data sent to be sent as ASCII characters of the hex value. If you want to send say hex byte 0xDF to the moonlite you have to send it two bytes of ASCII 'D' followed by ASCII 'F' so you would send the two hex bytes 0x44 and 0x46.

0x is the 'C' notation that the following number is in hex format.

It's because ASCII was the standard format for sending data over RS-232 serial links when it was developed many years ago using teletype machines to send readable data.

ASCII character set: Note that it is only 7 bit data, 0-127. Although a byte was sent, bit 7 (MSB) was undefined so sending an 8 bit hex value was unreliable as the (MSB) could get removed in transmission. 

asciifull.png.808ed209501976d019ed37c63aabd10e.png

Alan

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.