Hello
does anyone have an idea of the commands that Pyxis sends to the rotator and the denomination.
This would be to create arduino code that works with this driver, of course this is possible.

Thank you very much for your help.

Read More...

hello Jasem
I have a question, would it not be easier to take the Pyxis driver which is only for a rotator and adapt the arduino code of the nightcrawler to the Pyxis driver or is it not possible?
Unless I find the Pyxis arduino code, but for the moment I haven't found anything.

See you soon
Christophe

Read More...

hello
so this is where I need to edit

################ NightCrawler Focusing Rotator ################

SET(nightcrawler_SRC
${CMAKE_CURRENT_SOURCE_DIR}/drivers/rotator/nightcrawler.cpp) !!! here only ? !!!

add_executable(indi_nightcrawler_focus ${nightcrawler_SRC})
target_link_libraries(indi_nightcrawler_focus indidriver)
install(TARGETS indi_nightcrawler_focus RUNTIME DESTINATION bin)

I have just taken QTCreator, it seems to me much more complex to use, I will look at it and try to understand its functioning

Read More...

ok
so I'm copying and changing the names here for me
/home/christophe/Projects/indi/drivers/rotator
and the new file I can call "mynightcrawler" in h. and cpp.

but i can't find the way to get there
INDI CMakelists.txt

I'm sorry again for my ignorance on the subject
Christophe

Read More...

sorry again,
but I didn't quite understand that
**
You can rename the source files, and then look for nightcrawel in CMakeLists.txt and just copy the section for it and rename everything accordingly.
**
what should I do?
I just have to find the files, copy them, modify and rename them ?
or do I have to make a new driver by modifying the original files ?

Read More...

hello Jasem
so I'll try to modify the driver and remove the parts that I think are useless.
But where can I see the commands in the driver, that it sends to the arduino, because I need to find the "home" command of the rotator, and the command to give an angle from the serial terminal of the IDE, to control the modicication of the code without going through kstars for my tests.

And thank you for the link to the other rotator drivers, but is there also one online for the arduino.

Thanks again.

Read More...

Hello
One more question Jasem, how do I rename the driver that I modify so that I still have the original.
How do I install the modified driver and with which file do I have to do it?

Thanks again.

Read More...

Hello Jasem
then this is my problem, I'm really not expert in indi code, but if I look at the nightcrawler.h code there is a lot of parts I could remove, I think, that have nothing to do with the rotator, like ...

// Focus Sync
IUFillNumber(&SyncFocusN[0], "FOCUS_SYNC_OFFSET", "Ticks", "%.f", 0, 100000., 0., 0.);
IUFillNumberVector(&SyncFocusNP, SyncFocusN, 1, getDeviceName(), "FOCUS_SYNC", "Sync", MAIN_CONTROL_TAB, IP_RW, 0,
IPS_IDLE );

// Voltage
IUFillNumber(&VoltageN[0], "VALUE", "Value (v)", "%.2f", 0, 30., 1., 0.);
IUFillNumberVector(&VoltageNP, VoltageN, 1, getDeviceName(), "Voltage", "Voltage", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE );

// Temperature
IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Value (C)", "%.2f", -100, 100., 1., 0.);
IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature", MAIN_CONTROL_TAB,
IP_RO, 0, IPS_IDLE );

// Temperature offset
IUFillNumber(&TemperatureOffsetN[0], "OFFSET", "Offset", "%.2f", -15, 15., 1., 0.);
IUFillNumberVector(&TemperatureOffsetNP, TemperatureOffsetN, 1, getDeviceName(), "TEMPERATURE_OFFSET", "Temperature",
MAIN_CONTROL_TAB, IP_WO, 0, IPS_IDLE );

// Motor Step Delay
IUFillNumber(&FocusStepDelayN[0], "FOCUS_STEP", "Value", "%.f", 7, 100., 1., 7.);
IUFillNumberVector(&FocusStepDelayNP, FocusStepDelayN, 1, getDeviceName(), "FOCUS_STEP_DELAY", "Step Rate", SETTINGS_TAB,
IP_RW, 0, IPS_IDLE );


On the other hand I can't find the function that kstars sends to the arduino to tell it to do the GoHome

I'm not sure if you have the time to do it, but I'm sure you can figure out how to do it, so I'm not sure if you have the time.

Thanks again
Christophe

Read More...

Hello Jasem
then this is my problem, I'm really not expert in indi code, but if I look at the nightcrawler.h code there is a lot of parts I could remove, I think, that have nothing to do with the rotator, like ....

// Focus Sync IUFillNumber(&SyncFocusN[0], "FOCUS_SYNC_OFFSET", "Ticks", "%.f", 0, 100000., 0., 0.); IUFillNumberVector(&SyncFocusNP, SyncFocusN, 1, getDeviceName(), "FOCUS_SYNC", "Sync", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE );   // Voltage IUFillNumber(&VoltageN[0], "VALUE", "Value (v)", "%.2f", 0, 30., 1., 0.); IUFillNumberVector(&VoltageNP, VoltageN, 1, getDeviceName(), "Voltage", "Voltage", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE );   // Temperature IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Value (C)", "%.2f", -100, 100., 1., 0.); IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE );   // Temperature offset IUFillNumber(&TemperatureOffsetN[0], "OFFSET", "Offset", "%.2f", -15, 15., 1., 0.); IUFillNumberVector(&TemperatureOffsetNP, TemperatureOffsetN, 1, getDeviceName(), "TEMPERATURE_OFFSET", "Temperature", MAIN_CONTROL_TAB, IP_WO, 0, IPS_IDLE );   // Motor Step Delay IUFillNumber(&FocusStepDelayN[0], "FOCUS_STEP", "Value", "%.f", 7, 100., 1., 7.); IUFillNumberVector(&FocusStepDelayNP, FocusStepDelayN, 1, getDeviceName(), "FOCUS_STEP_DELAY", "Step Rate", SETTINGS_TAB, IP_RW, 0, IPS_IDLE );   // Limit Switch   IUFillLight(&LimitSwitchL[OUT_SWITCH], "OUT_SWITCH", "Focus Out Limit", IPS_OK); IUFillLight(&LimitSwitchL[IN_SWITCH], "IN_SWITCH", "Focus In Limit", IPS_OK); IUFillLightVector(&LimitSwitchLP, LimitSwitchL, 3, getDeviceName(), "LIMIT_SWITCHES", "Limit Switch", SETTINGS_TAB, IPS_IDLE); 
Because it's a part that doesn't fit me for the rotator ?

On the other hand I can't find the function that kstars sends to the arduino to tell it to do the GoHome

I'm not sure if you have the time to do it, but I'm sure you can figure out how to do it, so I'm not sure if you have the time.

Thanks again
Christophe
 

Read More...

Hello
So, indeed I would like to adapt an arduino code for this driver.
I already have the one for the driver, but it is too complicated because it is also for a focuser, so I would like to try to make a simpler one.

And my second question is to know if there is a way to modify the nightcrawler driver to make a simpler one, just for a rotator.

Like for example:
I would just need in the configurations, the "HOME" with the position that we want (from 0 to 360 °) to choose.
And to be able to do it either by pressing a button, or, automatically at the beginning of its use.

I don't know if it's possible

See you soon
Christophe

Read More...

Well, I guess I'm not having much luck right now.
I'm waiting for someone to explain to me or to tell me that it's not possible either to modify the display of the driver in kstars or to know the commands and the returns that the driver sends.

see you soon
Christophe

Read More...

well, I can't put it as an attachment, so
I put you the code

#include <AccelStepper.h>     // https://www.pjrc.com/teensy/td_libs_AccelStepper.html

#define EnablePin 12
#define IN1 4 
#define IN2 5 
#define IN3 6 
#define IN4 7 
#define MotorInterfaceType 4

#include <EEPROM.h>

// EEPROM addresses
#define FOCUSER_POS_START 0
#define STEPPER_SPEED_ADD 3

AccelStepper stepper(MotorInterfaceType, IN1, IN2, IN3, IN4);

// Global vars
boolean moving = false;
boolean hold = false;
boolean reversed;
boolean positionSaved;               // Flag indicates if stepper position was saved as new focuser position
boolean firstPrint = false;
boolean homeFound = true;
String inputString;                  // Serial input command string (terminated with \n)
boolean findingHome = false;

// *************  this value must be changed for each specific setup ***************************************
long maxSteps = 505960;  // **** steps needed for 2 complete revolutions.  prevent cord wrap.
long minStep = 0;
//  Must also enter this value/720 = steps/degree for first time ASCOM driver setup, click "properties
// ******************************************************************************************************

int manualMoveStepSize = 50;  //higher number for faster manual moves
int findHomeStepSize = 100; //adjusts finding home speed

int buttonStateCW = HIGH;
int buttonStateCCW = HIGH;
boolean manualMoveCW = false;
boolean manualMoveCCW = false;

int HEState = 0;
long lastDebounceTime = 0;
long debounceDelay = 20;

void setup()
{
  // Initialize serial
  Serial.begin(57600);
  pinMode(EnablePin, OUTPUT);
  analogWrite(EnablePin, 0);

  // Initialize stepper motor
  stepper.setMaxSpeed(200);// 5000 works good,  use 500000 for confrom test1000 geared rotator10000 for geared stepper   200 for non-geared large stepper(500 max)  also may depend on what else is on loop()
  stepper.setAcceleration(1000);//1000 for geared rotator  10000 for geared stepper    1000 for non-geared large stepper
  //stepper.setCurrentPosition(readFocuserPos());
  stepper.setCurrentPosition(0);
  positionSaved = true;
  inputString = "";
  reverseDir(false);
}

void loop()
{
  if (findingHome == true) {
    findHome();
  }

  // Stepper loop
  if (stepper.distanceToGo() == 0) {
    if (hold == false) {
      analogWrite(EnablePin, HIGH);
    }
  } else {
    analogWrite(EnablePin, 200);
  }
  if (stepper.distanceToGo() == 0 && !positionSaved) {
    saveFocuserPos(stepper.currentPosition());
    positionSaved = true;
  }
  if (stepper.distanceToGo() != 0 && !firstPrint) {
    firstPrint = true;
  }

  if (stepper.distanceToGo() != 0) {
    moving = true;
  } else {
    moving = false;
  }
  stepper.run();
}

// Interrupt serial event
void reverseDir(boolean rev) {
  stepper.setPinsInverted(rev, false, false);  //for FSQ85(true, false, false) ---  for TSA 120should be (false, false, false)  (dir, step, enable)
  //not reversed is std setup for tsa-120
  reversed = rev;
}
void Hold(boolean conthold) {
  hold = conthold;
}

void serialEvent() {
  while (Serial.available() > 0) {
    char inChar = (char)Serial.read();
    if (inChar == ':' || inChar == '#') {
      if (inputString == "PV") inputString = "V"; // Version
      if (inputString == "GA") inputString = "B"; // bit 1 for switch 2
      if (inputString == "SH") inputString = "H"; // Starts the Find Home routine
      if (inputString == "GS") inputString = "Z"; // bit 2 for In limit switch
      if (inputString == "GT") inputString = "D"; // Sensor temperature in tenths of a degree, ex: 25°C = 250d
      if (inputString == "GV") inputString = "E"; // System voltage in tenths of a volt, ex 12.0V = 120d
      if (inputString == "PD") inputString = "D"; // Set the display brightness
      if (inputString == "PL") inputString = "D"; // Set the display sleep brightness
      if (inputString == "PF") inputString = "F"; // Gets the current focuser type. Ex: "2.5 NC#"
      if (inputString == "PS") inputString = "X"; // Gets the current focuser serial number
      if (inputString == "PU") inputString = "W"; // Gets a user defined field
      if (inputString == "PE") inputString = "C"; // Enables or disables the encoders
      if (inputString == "PR") inputString = "J"; // Issues a reset
      if (inputString == "Pt") inputString = "D"; // Adjusts the temperature offset
      if (inputString == "Pu") inputString = "Y"; // Sets the user text field
      serialCommand(inputString);
      inputString = "";
    }
    else {
      inputString += inChar;
    }
  }
}

void serialCommand(String command) {
  String param = command.substring(4);
  String comando = command.substring(0, 3); //:2SN 12345678#
  if (comando == "2GP") command = "G"; // Current position count, 8 digits, signed, 0 padding
  if (comando == "1GP") command = "K"; // DUMMY Current position
  if (comando == "3GP") command = "K"; // DUMMY Current position
  if (comando == "2GM") command = "Q"; // IS MOVING
  if (comando == "2GN") command = "A"; // New (or Target) position count, 8 digits, signed, 0 padding
  if (comando == "2GR") command = "A"; // Motor step delay in 100 microsecond intervals
  if (comando == "2SQ") command = "S"; // Stops motor
  if (comando == "2SM") command = "A"; // Starts motor to move to the “NEW” focus position
  if (comando == "2SP") command = "P"; // Set the current position, 32 bit value, signed
  if (comando == "2SN") command = "M"; // Move to the New position count, 32 bit value, signed
  if (comando == "1SR") command = "A"; // Set the motor step rate in 100 microsecond intervals.
  if (comando == "2SR") command = "A"; // Set the motor step rate in 100 microsecond intervals.
  if (comando == "3SR") command = "A"; // Set the motor step rate in 100 microsecond intervals.

  //Serial.println(command);

  switch (command.charAt(0)) {
    case 'Q':
      if (moving == true) {
        Serial.println("01#");
      } else {
        Serial.println("00#");
      }
    case 'Y':
      Serial.println("RC 8#");
      break;
    case 'K':
      Serial.println("30000#");
      break;
    case 'A':
      Serial.println("#");
      break;
    case 'B':
      Serial.println("00#");
      break;
    case 'Z':
      Serial.println("00#");
      break;
    case 'D':
      Serial.println("105#");
      break;
    case 'E':
      Serial.println("123#");
      break;
    case 'F':
      Serial.println("3.5 NC#");
      break;
    case 'X':
      Serial.println("20200516#");
      break;
    case 'W':
      Serial.println("StarPI Rotator#");
      break;
    case 'G':
      printCurrentPosition();
      break;
    case 'P':
      saveCurrentPos(stringToLong(param));
      break;
    case 'H':    // find home
      if (param = 2) findHome();
      break;
    case 'M':
      moveStepper(stringToLong(param), false);
      break;
    case 'S':
      halt();
      break;
    case 'R':
      int value;
      value = (stringToNumber(param));
      if (value == 0) {
        reverseDir(false);
      } else {
        reverseDir(true);
      }
      break;
    case 'C':// continuos hold
      int value2;
      value2 = (stringToNumber(param));
      if (value2 == 0) {
        Hold(false);
      } else {
        Hold(true);
      }
      Serial.println("#");
      break;
    case 'V':
      Serial.println("1.3#");
      break;
    case 'J': // Reset Arduino myFocuserPro2 controller
      software_Reboot();
      break;
  }
}

void printCurrentPosition() {
  Serial.print("00");
  if (stepper.currentPosition() < 100000) Serial.print("0");
  if (stepper.currentPosition() < 10000) Serial.print("0");
  if (stepper.currentPosition() < 1000) Serial.print("0");
  if (stepper.currentPosition() < 100) Serial.print("0");
  if (stepper.currentPosition() < 10) Serial.print("0");
  Serial.print(stepper.currentPosition());
  Serial.println("#");
}

void moveStepper(long newPos, boolean manualMove) {
  Serial.println("#");
  if (findingHome == true) {
    stepper.moveTo(newPos);
  return;
  }

  if (newPos != stepper.currentPosition()) {
    if (newPos < minStep || newPos > maxSteps) {
      return;
    } else {
      stepper.moveTo(newPos);
      positionSaved = false;
      firstPrint = false;
    }
  }
}

void halt() {
  Serial.println("#");
  stepper.stop();
}

void saveCurrentPos(long newPos) {
  Serial.println("#");
  if (newPos < minStep) newPos = minStep;
  stepper.setCurrentPosition(newPos);
  moveStepper(newPos, false);
  saveFocuserPos(newPos);
  positionSaved = true;
}

void findHome() {
  Serial.println("#");
  long newPos = maxSteps / 4;
  homeFound = true;
  findingHome = false;
  saveCurrentPos(newPos);
}
// reboot the Arduino
void software_Reboot() {
  // jump to the start of the program
  asm volatile ( "jmp 0");
}

void saveFocuserPos(long newPos) {
  writeLong(getSaveFocuserPosAddress() + 1, newPos);
}

long readFocuserPos() {
  return readLong(getReadFocuserPosAddress() + 1);
}

void writeWord(word address, word value) {
  EEPROM.update(address, lowByte(value));
  EEPROM.update(address + 1, highByte(value));
}

word readWord(word address) {
  return word(EEPROM.read(address + 1), EEPROM.read(address));
}

long readLong(word address) {
  word lowWord = readWord(address);
  word highWord = readWord(address + 2);
  return lowWord + highWord * 65536;
}

void writeLong(word address, long value) {
  word lowWord = value % 65536;
  word highWord = value / 65536;
  writeWord(address, lowWord);
  writeWord(address + 2, highWord);
}

int stringToNumber(String thisString) {
  int i, value = 0, length;
  length = thisString.length();
  for (i = 0; i < length; i++) {
    value = (10 * value) + thisString.charAt(i) - (int) '0';
  }
  return value;
}

long stringToLong(String thisString) {
  boolean neg = false;
  if (thisString.indexOf("-") == 0) {
    thisString = thisString.substring(1);
    neg = true;
  }
  //Serial.println(thisString);
  long value = 0;
  int i, length;
  length = thisString.length();
  for (i = 0; i < length; i++) {
    value = (10 * value) + thisString.charAt(i) - (int) '0';
  }
  if (neg == true) {
    value = maxSteps - value;
  }
  return value;
}

// Simple EEPROM wear leveling
int getSaveFocuserPosAddress() {
  for (byte x = 0; x < 20; x++) {
    int address = FOCUSER_POS_START + 5 * x;
    if (EEPROM.read(address) == 0) {
      EEPROM.update(address, 0xFF);
      return address;
    }
  }
  // Array is full, erase it and start from 0 - takes about 100ms
  for (byte x = 0; x < 20; x++) {
    EEPROM.update(FOCUSER_POS_START + 5 * x, 0);
    EEPROM.update(FOCUSER_POS_START, 0xFF);
    return FOCUSER_POS_START;
  }
}

int getReadFocuserPosAddress() {
  for (byte x = 0; x < 20; x++) {
    int address = FOCUSER_POS_START + 5 * x;
    if (EEPROM.read(address) == 0) {
      return FOCUSER_POS_START + 5 * (x - 1);
    }
  }
}


Read More...

helloafter opening a topic to make a rotator, because although I can make the driver work with my project, I need information about this driver.First thing, how can I find the commands that the driver sends to the rotator.because I can't make the "GoHome" work and I would like to simulate it live in the arduino terminal to check if I have the right output and if the command is good.The second thing is that it is possible to remove the part that is used for the focus in the tab of kstars and in the arduino code, or it is a problem?
Thank you 

 

Read More...

Porchet replied to the topic 'Need help for rotator project' in the forum. 4 weeks ago

Hello
can you tell me where is the file of a driver in kstars,
because I would like to find which command it sends to the arduino and if it's possible to modify the layout (for a better translation in french).

Thanks a lot
Christophe

Read More...

Porchet replied to the topic 'Need help for rotator project' in the forum. 4 weeks ago

Hi,
I've managed to get the code to work with the TB6612, but I don't know if I have all the functions.
I have a question when you select a rotator, can you control the orientation of the yellow square directly on the star map after the first photo?
Because that would be great!
Best Regards
Chris

Read More...