×

INDI Library v2.0.7 is Released (01 Apr 2024)

Bi-monthly release with minor bug fixes and improvements

KStars with sound fun!

  • Posts: 173
  • Thank you received: 19

KStars with sound fun! was created by Jon

While I was adding in some functionality to the ZEQ25 driver (fixed MoveNS and MoveWE functions and added parking/unparking), I decided to have a little fun and throw in a basic sound function (for personal use only)......
I always liked the speech sound feedback option in EQMOD. Since that isn't an option for the ZEQ25 mount, I took advantage of the power of INDI to make it happen.

--Jon
Last edit: 7 years 8 months ago by Jon.
7 years 8 months ago #9555

Please Log in or Create an account to join the conversation.

Replied by Jasem Mutlaq on topic KStars with sound fun!

Video marked as private?
7 years 8 months ago #9556

Please Log in or Create an account to join the conversation.

  • Posts: 173
  • Thank you received: 19

Replied by Jon on topic KStars with sound fun!

I'm not sure why...maybe try a link instead?

--Jon

7 years 8 months ago #9557

Please Log in or Create an account to join the conversation.

Replied by Jasem Mutlaq on topic KStars with sound fun!

So how did you do it?
7 years 8 months ago #9558

Please Log in or Create an account to join the conversation.

  • Posts: 173
  • Thank you received: 19

Replied by Jon on topic KStars with sound fun!

I kind of cheated and just added in a basic system call to mplayer like this:
int LX200ZEQ25::audio_alert(const char * path)
{
 
    system(path);
  	return 0;
}

and call it with:
audio_alert("mplayer '/home/goto_in_progress.wav'");

in various places like the GoTo function...

I fixed the motion control by editing as follows:
bool LX200ZEQ25::SetSlewRate(int index)
{
   // Convert index to Meade format
   //index = 3 - index;
 
   if (isSimulation() == false && setZEQ25SlewMode(PortFD, index) < 0)
   {
       SlewRateSP.s = IPS_ALERT;
       IDSetSwitch(&SlewRateSP, "Error setting slew mode.");
      return false;
   }
 
   SlewRateSP.s = IPS_OK;
   IDSetSwitch(&SlewRateSP, NULL);
   return true;
}
 
int LX200ZEQ25::ZEQ25MoveTo(int fd, int direction)
{
    DEBUGF(DBG_SCOPE, "<%s>", __FUNCTION__);
    int nbytes_write=0;
 
    switch (direction)
    {
    case LX200_NORTH:
        DEBUGF(DBG_SCOPE, "CMD <%s>", ":mn#");
        tty_write_string(fd, ":mn#", &nbytes_write);
        break;
    case LX200_WEST:
        DEBUGF(DBG_SCOPE, "CMD <%s>", ":mw#");
        tty_write_string(fd, ":mw#", &nbytes_write);
        break;
    case LX200_EAST:
        DEBUGF(DBG_SCOPE, "CMD <%s>", ":me#");
        tty_write_string(fd, ":me#", &nbytes_write);
        break;
    case LX200_SOUTH:
        DEBUGF(DBG_SCOPE, "CMD <%s>", ":ms#");
        tty_write_string(fd, ":ms#", &nbytes_write);
        break;
    default:
        break;
    }
 
    tcflush(fd, TCIFLUSH);
    return 0;
}
 
int LX200ZEQ25::setZEQ25SlewMode(int fd, int slewMode)
{
  DEBUGF(DBG_SCOPE, "<%s>", __FUNCTION__);
  int error_type;
  int nbytes_write=0;
 
  switch (slewMode)
  {
    case SLEW_MAX:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":SR9#");
   if ( (error_type = tty_write_string(fd, ":SR9#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    case SLEW_FIND:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":SR6#");
     if ( (error_type = tty_write_string(fd, ":SR6#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    case SLEW_CENTERING:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":SR4#");
    if ( (error_type = tty_write_string(fd, ":SR4#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    case SLEW_GUIDE:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":SR1#");
    if ( (error_type = tty_write_string(fd, ":SR1#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    default:
     break;
   }
 
   tcflush(fd, TCIFLUSH);
   return 0;
 
}
 
 
bool LX200ZEQ25::MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command)
{
    int current_move = (dir == DIRECTION_WEST) ? LX200_WEST : LX200_EAST;
 
    switch (command)
    {
        case MOTION_START:
        if (isSimulation() == false && ZEQ25MoveTo(PortFD, current_move) < 0)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Error setting W/E motion direction.");
            return false;
        }
        else
           DEBUGF(INDI::Logger::DBG_SESSION,"Moving to the %s.", (current_move == LX200_WEST) ? "West" : "East");
        break;
 
        case MOTION_STOP:
        if (isSimulation() == false && ZEQ25HaltMovement(PortFD, current_move) < 0)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Error stopping W/E motion.");
            return false;
        }
        else
            DEBUGF(INDI::Logger::DBG_SESSION, "Movement to the %s halted.", (current_move == LX200_WEST) ? "West" : "East");
        break;
    }
 
    return true;
}
 
bool LX200ZEQ25::MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command)
{
    int current_move = (dir == DIRECTION_NORTH) ? LX200_NORTH : LX200_SOUTH;
 
    switch (command)
    {
        case MOTION_START:
        if (isSimulation() == false && ZEQ25MoveTo(PortFD, current_move) < 0)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Error setting N/S motion direction.");
            return false;
        }
        else
           DEBUGF(INDI::Logger::DBG_SESSION,"Moving to the %s.", (current_move == LX200_NORTH) ? "North" : "South");
        break;
 
        case MOTION_STOP:
        if (isSimulation() == false && ZEQ25HaltMovement(PortFD, current_move) < 0)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Error stopping N/S motion.");
            return false;
        }
        else
            DEBUGF(INDI::Logger::DBG_SESSION, "Movement to the %s halted.", (current_move == LX200_NORTH) ? "North" : "South");
        break;
    }
 
    return true;
}
 
int LX200ZEQ25::ZEQ25HaltMovement(int fd, int direction)
{
    DEBUGF(DBG_SCOPE, "<%s>", __FUNCTION__);
    int error_type;
    int nbytes_write=0;
 
  switch (direction)
  {
    case LX200_NORTH:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":q#");
       if ( (error_type = tty_write_string(fd, ":q#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    case LX200_WEST:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":q#");
     if ( (error_type = tty_write_string(fd, ":q#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    case LX200_EAST:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":q#");
      if ( (error_type = tty_write_string(fd, ":q#", &nbytes_write)) != TTY_OK)
    	return error_type;
     break;
    case LX200_SOUTH:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":q#");
    if ( (error_type = tty_write_string(fd, ":q#", &nbytes_write)) != TTY_OK)
    	return error_type;
    break;
    case LX200_ALL:
      DEBUGF(DBG_SCOPE, "CMD <%s>", ":q#");
    if ( (error_type = tty_write_string(fd, ":q#", &nbytes_write)) != TTY_OK)
    	   return error_type;
     break;
    default:
     return -1;
    break;
  }
 
  tcflush(fd, TCIFLUSH);
  return 0;
 
}
 
 

and added in park and unpark functions:
bool LX200ZEQ25::Park()
{
    DEBUGF(DBG_SCOPE, "<%s>", __FUNCTION__);
    char slewNum[2];
    int error_type;
    int nbytes_write=0, nbytes_read=0;
 
    DEBUGF(DBG_SCOPE, "CMD <%s>", ":MH#");
 
    if ( (error_type = tty_write_string(PortFD, ":MH#", &nbytes_write)) != TTY_OK)
        return false;
 
    error_type = tty_read(PortFD, slewNum, 1, 3, &nbytes_read);
 
    if (nbytes_read < 1)
    {
        DEBUGF(DBG_SCOPE, "RES ERROR <%d>", error_type);
        return false;
    }
 
    /* We don't need to read the string message, just return corresponding error code */
    tcflush(PortFD, TCIFLUSH);
 
    DEBUGF(DBG_SCOPE, "RES <%c>", slewNum[0]);
 
    ParkSP.s = IPS_BUSY;
    TrackState = SCOPE_PARKING;
    IDMessage(getDeviceName(), "Parking telescope in progress...");
    audio_alert("mplayer '/home/mount_parking_in_progress.wav'");
    return true;
 
}
 
 
bool LX200ZEQ25::UnPark()
{
    if (ZEQ25_isHome())
 
		{
			SetParked(false);
    		TrackState = SCOPE_IDLE;
    		IDMessage(getDeviceName(), "Mount is unparked...");
			return true;
		}
 
			IDMessage(getDeviceName(), "Error unparking Telescope");
			return false;
 
}
 

I also created a function to test if the mount is in the home position:
bool LX200ZEQ25::ZEQ25_isHome()
{
    char cmd[16];
    int errcode = 0;
    char errmsg[MAXRBUF];
    char response[8];
    int nbytes_read=0;
    int nbytes_written=0;
 
    strncpy(cmd, ":AH#", 16);
 
    DEBUGF(INDI::Logger::DBG_DEBUG, "CMD (%s)", cmd);
 
    if ( (errcode = tty_write(PortFD, cmd, 4, &nbytes_written)) != TTY_OK)
    {
        tty_error_msg(errcode, errmsg, MAXRBUF);
        DEBUGF(INDI::Logger::DBG_ERROR, "%s", errmsg);
        return false;
    }
 
    if ( (errcode = tty_read(PortFD, response, 1, 3, &nbytes_read)))
    {
        tty_error_msg(errcode, errmsg, MAXRBUF);
        DEBUGF(INDI::Logger::DBG_ERROR, "%s", errmsg);
        return false;
    }
 
 
 
 
    if (nbytes_read > 0)
    {
        response[nbytes_read] = '\0';
        DEBUGF(INDI::Logger::DBG_DEBUG, "RES (%s)", response);
 
        tcflush(PortFD, TCIFLUSH);
 
        if (response[0] == '1')
        { 
 
 
            return true;
        }
        else
            return false;
    }
 
    DEBUGF(INDI::Logger::DBG_ERROR, "Only received #%d bytes, expected 1.", nbytes_read);
    return false;
}
 
 

There are a few other changes too.....certainly not perfect but it works. I didn't offer up the code as it depends on mplayer and I know we aren't supposed to do that. For me, privately, it's a solution.

For the audio sound bites, there are a ton of free and paid online text to speech converters. I edited mine in Audacity.

--Jon
Last edit: 7 years 8 months ago by Jon.
7 years 8 months ago #9559

Please Log in or Create an account to join the conversation.

  • Posts: 173
  • Thank you received: 19

Replied by Jon on topic KStars with sound fun!

Because I use an Odroid for control, I use RDP to connect to it and there are some other changes that I needed to make to pipe sound to my Windows machine running the VM....

--Jon
7 years 8 months ago #9560

Please Log in or Create an account to join the conversation.

Replied by Jasem Mutlaq on topic KStars with sound fun!

hmmm, there is already sound support for some Ekos functions, I don't see why it can't be extended for mount stuff. Can you share the sound files?
7 years 8 months ago #9561

Please Log in or Create an account to join the conversation.

  • Posts: 173
  • Thank you received: 19

Replied by Jon on topic KStars with sound fun!

That would be awesome....
I'll have to look into the licensing of the sound files. I bought mine but I'm not sure if I can use them elsewhere. I will find a way to do it though. Do you think we would need something for other events besides the ones I have currently?
If the licensing is a problem, could you extend the text vectors and just allow end users to specify the paths to their own sound files for certain events? That would also cover issues with language support.

--Jon
Last edit: 7 years 8 months ago by Jon.
7 years 8 months ago #9562

Please Log in or Create an account to join the conversation.

Replied by Jasem Mutlaq on topic KStars with sound fun!

Users can put whatever sound they like as it is currently done with Ekos events using KDE Notifications. It's just a matter of adding notifications for mount events.
7 years 8 months ago #9563

Please Log in or Create an account to join the conversation.

  • Posts: 173
  • Thank you received: 19

Replied by Jon on topic KStars with sound fun!

Per the Limitation on Rights on Audio-Files:

"Limitation on Rights on Audio-Files
Except for Radio and TV Broadcast you have all rights on the audio-files purchased through the Service if they conform to this TOS. For Radio and TV Broadcast you have to get a written authorization from Acapela Group. Please use our Contact form for this purpose."

I see no reason I cannot share them.....

--Jon

File Attachment:

File Name: MountSoundFiles.zip
File Size:231 KB
7 years 8 months ago #9564
Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 72
  • Thank you received: 21

Replied by Philippe on topic KStars with sound fun!

Not only funny. Looks just quit good item to be added in kstar.
Philippe
Philippe Besson
Skywatcher HEQ5, Televue 101-IS, Takahashi FS-60CB
Focus Boss II with OptecInc TCF-S focuser and Starlight Instruments HSM20 handy stepper motor
Guiding camera ZWO ASI120MM
Filterwheel OptecInc IFW
Camera not set yet
Switzerland
7 years 8 months ago #9575

Please Log in or Create an account to join the conversation.

Time to create page: 0.445 seconds