Jump to content

NLCbanner2024.jpg.2478be509670e60c2d6efd04834b8b47.jpg

Nexstar Raspberry Pi Controller


tekkydave

Recommended Posts

synscan.  But the only difference is that the syncan is supplied with the hand controller - the mounts themselves are identical.  For computer control you don't want the handset (and shouldn't try to use it) PC connects via USB to serial adapter to the socket the hand controller plugs into.

Link to comment
Share on other sites

Now I'm trying to work out how on earth I managed to setup Ekos last time.  I have the instructions but they bear no relationship to what's on my laptop in KStars/Ekos :(  1. Select Profile is greyed out!  They don't say where the Profile Editor is :(

Ekos Setup 01.JPG

Edited by Gina
Link to comment
Share on other sites

I wish I could do that with the Celestron Nexstar mount but you have to keep the HC connected. The serial interface is in the base of the HC. Fortunately I have the StarSense accessory and GPS so a few buttons to press and it aligns itself in a few minutes. After that the operation will be remote via KStars/Ekos.

  • Like 1
Link to comment
Share on other sites

52 minutes ago, Gina said:

Thanks Dave :)  YIPPEE!  It's working :)

Network devices 01.JPGNetwork devices 02.JPG

In the Homehub you can force a device to always pick up the same ip address. That is if you have not already forced it to have a static ip and are relying on dhcp from the Homehub. It's useful if you have no way of setting the ip on the device itself and want a fixed address.

  • Like 1
Link to comment
Share on other sites

It's suddenly become live - the Select Profile is available and I've been able to click the + button to Add Profile :)  now set it up and it's WORKING :)  I can slew from the settee :):hello2::hello2:

Edited by Gina
  • Like 2
Link to comment
Share on other sites

Guess the next thing is to try it on the observatory but maybe I should make a backup first! :)  Then the next job will be check out KStars and see if I can find a target.

Link to comment
Share on other sites

Backed up onto HD of W7 desktop :)  Tried writing the image onto another 8GB micro SD card but got an error saying the disk wasn't big enough - seems different makes have slightly different sizes.  I have one or two 32BG cards if needed.

Link to comment
Share on other sites

Put micro SD card back in RPi and powered up.  WiFi connection showing fine in router device list with same IP address as it should be having been set up as static BUT can't connect with Putty :(  I need to connect with SSH/Putty as indiserver needs setting up.

Link to comment
Share on other sites

OK so WiFi is not essential but it should work.  I have the HomePlug devices I can use to provide a cable connection in the observatory if necessary but the idea of the RPi 3 was WiFi and to reduce cable count to absolute minimum.

Link to comment
Share on other sites

Think I'll see if I can get the RPi working in my all sky cam.  ASI187MM + focuser with Astroberry Focuser + dew heater control with Astroberry Board.  I shall need to look at the Astroberry board driver C++ code to see which GPIO lines are used and modify if wanted (and recompile).

I shall need to find out how to have SSH and WiFi set ready to receive commands to enable the indiserver OR how to make indiserver auto-start with required drivers chosen.

Link to comment
Share on other sites

Lists of GPIO lines used in Astroberry board and focuser - they don't clash so no need to alter :)  The board pins are all outputs and would control relays on the associated hardware despite being called IN*.

Astroberry Board
Astroberry Board 01.JPG

Astroberry Focuser
Astroberry Focus 01.JPG

Link to comment
Share on other sites

I've been studying the C++ code for the focuser.  For controlling my ASC focus the code will be alright as it is though could be simplified with the Ekos controls simplified to match.  All I need for the ASC focus is STEP and DIRection.  Fine control is all that's required as the lens can start at approximate focus.  For DSO imaging it would be useful to have two speeds but I have yet to see how auto-focus works.

The Astroberry Focuser code allows for 6 different speeds and uses a mode of control not available on the A4988 driver module and that is output GPIO pin floating.  Now I'm wondering why such a wide range of speeds has been allowed for and hence coded.  Maybe the author just wanted to provide as much control as available with the hardware.  I shall look at the Ekos controls the focuser driver provides and see if all these speeds are used - I very much suspect NOT.  Auto-focusing is something else to look at as I said above and would be very useful for imaging sessions.

Link to comment
Share on other sites

Here is the Astroberry Focus .cpp file :-

/*******************************************************************************
  Copyright(c) 2014 Radek Kaczorek  <rkaczorek AT gmail DOT com>

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License version 2 as published by the Free Software Foundation.
 .
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.
 .
 You should have received a copy of the GNU Library General Public License
 along with this library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.
*******************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <memory>
#include <bcm2835.h>

#include "rpi_focus.h"

// We declare an auto pointer to focusRpi.
std::auto_ptr<FocusRpi> focusRpi(0);

// Stepper motor takes 4 miliseconds to move one step = 250 steps per second (real rate = 240,905660377)
// 1) focusing from min to max takes 7 evolutions
// 2) PG2528-0502U step motor makes 7 * (360deg/15degperstep)*72:1 = 1728 steps per evolution
// 3) MAX_STEPS for 7 evolutions should be 12096

#define MAX_STEPS 10000 // maximum steps focuser can travel from min=0 to max

#define STEP_DELAY 4 // miliseconds

// indicate GPIOs used - use P1_* pin numbers not gpio numbers (!!!)

//RPi B+
/*
#define DIR RPI_V2_GPIO_P1_07	// GPIO4
#define STEP RPI_V2_GPIO_P1_11	// GPIO17
#define M0 RPI_V2_GPIO_P1_15	// GPIO22
#define M1 RPI_V2_GPIO_P1_13	// GPIO27
#define SLEEP RPI_V2_GPIO_P1_16	// GPIO23
*/

//RPi 2
#define DIR RPI_BPLUS_GPIO_J8_07	// GPIO4
#define STEP RPI_BPLUS_GPIO_J8_11	// GPIO17
#define M0 RPI_BPLUS_GPIO_J8_15		// GPIO22
#define M1 RPI_BPLUS_GPIO_J8_13		// GPIO27
#define SLEEP RPI_BPLUS_GPIO_J8_16	// GPIO23


void ISPoll(void *p);


void ISInit()
{
   static int isInit = 0;

   if (isInit == 1)
       return;
   if(focusRpi.get() == 0)
   {
       isInit = 1;
       focusRpi.reset(new FocusRpi());
   }
}

void ISGetProperties(const char *dev)
{
        ISInit();
        focusRpi->ISGetProperties(dev);
}

void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
{
        ISInit();
        focusRpi->ISNewSwitch(dev, name, states, names, num);
}

void ISNewText(	const char *dev, const char *name, char *texts[], char *names[], int num)
{
        ISInit();
        focusRpi->ISNewText(dev, name, texts, names, num);
}

void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
{
        ISInit();
        focusRpi->ISNewNumber(dev, name, values, names, num);
}

void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
{
  INDI_UNUSED(dev);
  INDI_UNUSED(name);
  INDI_UNUSED(sizes);
  INDI_UNUSED(blobsizes);
  INDI_UNUSED(blobs);
  INDI_UNUSED(formats);
  INDI_UNUSED(names);
  INDI_UNUSED(n);
}

void ISSnoopDevice (XMLEle *root)
{
    ISInit();
    focusRpi->ISSnoopDevice(root);
}

FocusRpi::FocusRpi()
{
	setVersion(2,1);
}

FocusRpi::~FocusRpi()
{

}

const char * FocusRpi::getDefaultName()
{
        return (char *)"Astroberry Focuser";
}

bool FocusRpi::Connect()
{
    if (!bcm2835_init())
    {
		IDMessage(getDeviceName(), "Problem initiating Astroberry Focuser.");
		return false;
	}

    // init GPIOs
    std::ofstream exportgpio;
    exportgpio.open("/sys/class/gpio/export");
    exportgpio << DIR << std::endl;
    exportgpio << STEP << std::endl;
    exportgpio << M0 << std::endl;
    exportgpio << M1 << std::endl;
    exportgpio << SLEEP << std::endl;
    exportgpio.close();

    // Set gpios to output mode
    bcm2835_gpio_fsel(DIR, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(STEP, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(SLEEP, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
	
    IDMessage(getDeviceName(), "Astroberry Focuser connected successfully.");
    return true;
}

bool FocusRpi::Disconnect()
{
	// park focuser
	if ( FocusParkingS[0].s == ISS_ON )
	{
		IDMessage(getDeviceName(), "Astroberry Focuser is parking...");	
		MoveAbsFocuser(FocusAbsPosN[0].min);
	}
	
    // close GPIOs
    std::ofstream unexportgpio;
    unexportgpio.open("/sys/class/gpio/unexport");
    unexportgpio << DIR << std::endl;
    unexportgpio << STEP << std::endl;
    unexportgpio << M0 << std::endl;
    unexportgpio << M1 << std::endl;
    unexportgpio << SLEEP << std::endl;
    unexportgpio.close();
    bcm2835_close();
		
	IDMessage(getDeviceName(), "Astroberry Focuser disconnected successfully.");
    
    return true;
}

bool FocusRpi::initProperties()
{
    INDI::Focuser::initProperties();

    IUFillText(&PortT[0], "PORT", "Port","RPi GPIO");
    IUFillTextVector(&PortTP,PortT,1,getDeviceName(),"DEVICE_PORT","Ports",OPTIONS_TAB,IP_RO,0,IPS_OK);

    IUFillNumber(&FocusAbsPosN[0],"FOCUS_ABSOLUTE_POSITION","Ticks","%0.0f",0,MAX_STEPS,(int)MAX_STEPS/100,0);
    IUFillNumberVector(&FocusAbsPosNP,FocusAbsPosN,1,getDeviceName(),"ABS_FOCUS_POSITION","Position",MAIN_CONTROL_TAB,IP_RW,0,IPS_OK);

	IUFillNumber(&PresetN[0], "Preset 1", "", "%0.0f", 0, MAX_STEPS, (int)(MAX_STEPS/100), 0);
	IUFillNumber(&PresetN[1], "Preset 2", "", "%0.0f", 0, MAX_STEPS, (int)(MAX_STEPS/100), 0);
	IUFillNumber(&PresetN[2], "Preset 3", "", "%0.0f", 0, MAX_STEPS, (int)(MAX_STEPS/100), 0);
	IUFillNumberVector(&PresetNP, PresetN, 3, getDeviceName(), "Presets", "Presets", "Presets", IP_RW, 0, IPS_IDLE);

	IUFillSwitch(&PresetGotoS[0], "Preset 1", "Preset 1", ISS_OFF);
	IUFillSwitch(&PresetGotoS[1], "Preset 2", "Preset 2", ISS_OFF);
	IUFillSwitch(&PresetGotoS[2], "Preset 3", "Preset 3", ISS_OFF);
	IUFillSwitchVector(&PresetGotoSP, PresetGotoS, 3, getDeviceName(), "Presets Goto", "Goto", MAIN_CONTROL_TAB,IP_RW,ISR_1OFMANY,60,IPS_OK);

	IUFillNumber(&FocusBacklashN[0], "FOCUS_BACKLASH_VALUE", "Steps", "%0.0f", 0, (int)(MAX_STEPS/100), (int)(MAX_STEPS/1000), 0);
	IUFillNumberVector(&FocusBacklashNP, FocusBacklashN, 1, getDeviceName(), "FOCUS_BACKLASH", "Backlash", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

	IUFillSwitch(&FocusResetS[0],"FOCUS_RESET","Reset",ISS_OFF);
	IUFillSwitchVector(&FocusResetSP,FocusResetS,1,getDeviceName(),"FOCUS_RESET","Position Reset",OPTIONS_TAB,IP_RW,ISR_1OFMANY,60,IPS_OK);

	IUFillSwitch(&FocusParkingS[0],"FOCUS_PARKON","Enable",ISS_OFF);
	IUFillSwitch(&FocusParkingS[1],"FOCUS_PARKOFF","Disable",ISS_OFF);
	IUFillSwitchVector(&FocusParkingSP,FocusParkingS,2,getDeviceName(),"FOCUS_PARK","Parking Mode",OPTIONS_TAB,IP_RW,ISR_1OFMANY,60,IPS_OK);

	// set capabilities
        SetFocuserCapability(FOCUSER_CAN_ABS_MOVE | FOCUSER_CAN_REL_MOVE);

        controller->mapController("Focus In", "Focus In", INDI::Controller::CONTROLLER_BUTTON, "BUTTON_1");
        controller->mapController("Focus Out", "Focus Out", INDI::Controller::CONTROLLER_BUTTON, "BUTTON_2");
        controller->mapController("Abort Focus", "Abort Focus", INDI::Controller::CONTROLLER_BUTTON, "BUTTON_3");
        controller->initProperties();

    return true;
}

void FocusRpi::ISGetProperties (const char *dev)
{
    INDI::Focuser::ISGetProperties(dev);

    /* Add debug controls so we may debug driver if necessary */
    addDebugControl();

    return;
}

bool FocusRpi::updateProperties()
{

    INDI::Focuser::updateProperties();

    if (isConnected())
    {
		deleteProperty(FocusSpeedNP.name);
        defineNumber(&FocusAbsPosNP);
        defineSwitch(&FocusMotionSP);
		defineNumber(&FocusBacklashNP);
		defineSwitch(&FocusParkingSP);
		defineSwitch(&FocusResetSP);
    }
    else
    {
        deleteProperty(FocusAbsPosNP.name);
        deleteProperty(FocusMotionSP.name);
		deleteProperty(FocusBacklashNP.name);
		deleteProperty(FocusParkingSP.name);
		deleteProperty(FocusResetSP.name);
    }

    return true;
}

bool FocusRpi::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
{
	// first we check if it's for our device
	if(strcmp(dev,getDeviceName())==0)
	{

        // handle focus absolute position
        if (!strcmp(name, FocusAbsPosNP.name))
        {
			int newPos = (int) values[0];
            if ( MoveAbsFocuser(newPos) == IPS_OK )
            {
               IUUpdateNumber(&FocusAbsPosNP,values,names,n);
               FocusAbsPosNP.s=IPS_OK;
               IDSetNumber(&FocusAbsPosNP, NULL);
            }
            return true;
        }        

        // handle focus relative position
        if (!strcmp(name, FocusRelPosNP.name))
        {
			IUUpdateNumber(&FocusRelPosNP,values,names,n);
			
			//FOCUS_INWARD
            if ( FocusMotionS[0].s == ISS_ON )
				MoveRelFocuser(FOCUS_INWARD, FocusRelPosN[0].value);

			//FOCUS_OUTWARD
            if ( FocusMotionS[1].s == ISS_ON )
				MoveRelFocuser(FOCUS_OUTWARD, FocusRelPosN[0].value);

			FocusRelPosNP.s=IPS_OK;
			IDSetNumber(&FocusRelPosNP, NULL);
			return true;
        }

        // handle focus timer
        if (!strcmp(name, FocusTimerNP.name))
        {
			IUUpdateNumber(&FocusTimerNP,values,names,n);

			//FOCUS_INWARD
            if ( FocusMotionS[0].s == ISS_ON )
				MoveFocuser(FOCUS_INWARD, 0, FocusTimerN[0].value);

			//FOCUS_OUTWARD
            if ( FocusMotionS[1].s == ISS_ON )
				MoveFocuser(FOCUS_OUTWARD, 0, FocusTimerN[0].value);

			FocusTimerNP.s=IPS_OK;
			IDSetNumber(&FocusTimerNP, NULL);
			return true;
        }

        // handle focus backlash
        if (!strcmp(name, FocusBacklashNP.name))
        {
            IUUpdateNumber(&FocusBacklashNP,values,names,n);
            FocusBacklashNP.s=IPS_OK;
            IDSetNumber(&FocusBacklashNP, "Astroberry Focuser backlash set to %d", (int) FocusBacklashN[0].value);
            return true;
        }
	}
    return INDI::Focuser::ISNewNumber(dev,name,values,names,n);
}

bool FocusRpi::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
{
	// first we check if it's for our device
    if (!strcmp(dev, getDeviceName()))
    {
/*		
        // handle focus motion in and out
        if (!strcmp(name, FocusMotionSP.name))
        {
            IUUpdateSwitch(&FocusMotionSP, states, names, n);

			//FOCUS_INWARD
            if ( FocusMotionS[0].s == ISS_ON )
				MoveRelFocuser(FOCUS_INWARD, FocusRelPosN[0].value);

			//FOCUS_OUTWARD
            if ( FocusMotionS[1].s == ISS_ON )
				MoveRelFocuser(FOCUS_OUTWARD, FocusRelPosN[0].value);

            //FocusMotionS[0].s = ISS_OFF;
            //FocusMotionS[1].s = ISS_OFF;

			FocusMotionSP.s = IPS_OK;
            IDSetSwitch(&FocusMotionSP, NULL);
            return true;
        }
*/
        // handle focus presets
        if (!strcmp(name, PresetGotoSP.name))
        {
            IUUpdateSwitch(&PresetGotoSP, states, names, n);

			//Preset 1
            if ( PresetGotoS[0].s == ISS_ON )
				MoveAbsFocuser(PresetN[0].value);

			//Preset 2
            if ( PresetGotoS[1].s == ISS_ON )
				MoveAbsFocuser(PresetN[1].value);

			//Preset 2
            if ( PresetGotoS[2].s == ISS_ON )
				MoveAbsFocuser(PresetN[2].value);

			PresetGotoS[0].s = ISS_OFF;
			PresetGotoS[1].s = ISS_OFF;
			PresetGotoS[2].s = ISS_OFF;
			PresetGotoSP.s = IPS_OK;
            IDSetSwitch(&PresetGotoSP, NULL);
            return true;
        }
                
        // handle focus reset
        if(!strcmp(name, FocusResetSP.name))
        {
			IUUpdateSwitch(&FocusResetSP, states, names, n);

            if ( FocusResetS[0].s == ISS_ON && FocusAbsPosN[0].value == FocusAbsPosN[0].min  )
            {
				FocusAbsPosN[0].value = (int)MAX_STEPS/100;
				IDSetNumber(&FocusAbsPosNP, NULL);
				MoveAbsFocuser(0);
			}
            FocusResetS[0].s = ISS_OFF;
            IDSetSwitch(&FocusResetSP, NULL);
			
			return true;
		}

        // handle parking mode
        if(!strcmp(name, FocusParkingSP.name))
        {
			IUUpdateSwitch(&FocusParkingSP, states, names, n);
			IDSetSwitch(&FocusParkingSP, NULL);
			return true;
		}

        // handle focus abort - TODO
        if (!strcmp(name, AbortSP.name))
        {
            IUUpdateSwitch(&AbortSP, states, names, n);
            AbortS[0].s = ISS_OFF;
			AbortSP.s = IPS_OK;
            IDSetSwitch(&AbortSP, NULL);
            return true;
        }
        
    }
    return INDI::Focuser::ISNewSwitch(dev,name,states,names,n);
}

bool FocusRpi::ISSnoopDevice (XMLEle *root)
{
    controller->ISSnoopDevice(root);

    return INDI::Focuser::ISSnoopDevice(root);
}

bool FocusRpi::saveConfigItems(FILE *fp)
{
    IUSaveConfigText(fp, &PortTP);
    IUSaveConfigNumber(fp, &FocusRelPosNP);
    IUSaveConfigNumber(fp, &PresetNP);
    IUSaveConfigNumber(fp, &FocusBacklashNP);
	IUSaveConfigSwitch(fp, &FocusParkingSP);
    
    if ( FocusParkingS[0].s == ISS_ON )
		IUSaveConfigNumber(fp, &FocusAbsPosNP);

    controller->saveConfigItems(fp);

    return true;
}

IPState FocusRpi::MoveFocuser(FocusDirection dir, int speed, int duration)
{
	int ticks = (int) ( duration / STEP_DELAY);
    return 	MoveRelFocuser( dir, ticks);
}


IPState FocusRpi::MoveRelFocuser(FocusDirection dir, int ticks)
{
    int targetTicks = FocusAbsPosN[0].value + (ticks * (dir == FOCUS_INWARD ? -1 : 1));
    return MoveAbsFocuser(targetTicks);
}

IPState FocusRpi::MoveAbsFocuser(int targetTicks)
{
    if (targetTicks < FocusAbsPosN[0].min || targetTicks > FocusAbsPosN[0].max)
    {
        IDMessage(getDeviceName(), "Requested position is out of range.");
        return IPS_ALERT;
    }
    	
    if (targetTicks == FocusAbsPosN[0].value)
    {
        // IDMessage(getDeviceName(), "Astroberry Focuser already in the requested position.");
        return IPS_OK;
    }

	// set focuser busy
	FocusAbsPosNP.s = IPS_BUSY;
	IDSetNumber(&FocusAbsPosNP, NULL);

    // motor wake up
    bcm2835_gpio_write(SLEEP, HIGH);

	// set full step size
	SetSpeed(1);
	
	// check last motion direction for backlash triggering
	char lastdir = bcm2835_gpio_lev(DIR);

    // set direction
    const char* direction;    
    if (targetTicks > FocusAbsPosN[0].value)
    {
		// OUTWARD
		bcm2835_gpio_write(DIR, LOW);
		direction = " outward ";
	}
    else
	{
		// INWARD
		bcm2835_gpio_write(DIR, HIGH);
		direction = " inward ";
	}

    IDMessage(getDeviceName() , "Astroberry Focuser is moving %s", direction);

	// if direction changed do backlash adjustment
	if ( bcm2835_gpio_lev(DIR) != lastdir && FocusAbsPosN[0].value != 0 && FocusBacklashN[0].value != 0 )
	{
		IDMessage(getDeviceName() , "Astroberry Focuser backlash compensation by %0.0f steps...", FocusBacklashN[0].value);	
		for ( int i = 0; i < FocusBacklashN[0].value; i++ )
		{
			// step on
			bcm2835_gpio_write(STEP, HIGH);
			// wait
			bcm2835_delay(STEP_DELAY/2);
			// step off
			bcm2835_gpio_write(STEP, LOW);
			// wait 
			bcm2835_delay(STEP_DELAY/2);
		}
	}

	// process targetTicks
    int ticks = abs(targetTicks - FocusAbsPosN[0].value);

    for ( int i = 0; i < ticks; i++ )
    {
        // step on
        bcm2835_gpio_write(STEP, HIGH);
        // wait
        bcm2835_delay(STEP_DELAY/2);
        // step off
        bcm2835_gpio_write(STEP, LOW);
        // wait 
        bcm2835_delay(STEP_DELAY/2);

		// INWARD - count down
		if ( bcm2835_gpio_lev(DIR) == HIGH )
			FocusAbsPosN[0].value -= 1;

		// OUTWARD - count up
		if ( bcm2835_gpio_lev(DIR) == LOW )
			FocusAbsPosN[0].value += 1;

		IDSetNumber(&FocusAbsPosNP, NULL);
    }

    // motor sleep
    bcm2835_gpio_write(SLEEP, LOW);

    // update abspos value and status
    IDSetNumber(&FocusAbsPosNP, "Astroberry Focuser moved to position %0.0f", FocusAbsPosN[0].value);
	FocusAbsPosNP.s = IPS_OK;
	IDSetNumber(&FocusAbsPosNP, NULL);
	
    return IPS_OK;
}

bool FocusRpi::SetSpeed(int speed)
{
	/* Stepper motor resolution settings (for PG2528-0502U)
	* 1) 1/1   - M0=0 M1=0
	* 2) 1/2   - M0=1 M1=0
	* 3) 1/4   - M0=floating M1=0
	* 4) 1/8   - M0=0 M1=1
	* 5) 1/16  - M0=1 M1=1
	* 6) 1/32  - M0=floating M1=1
	*/

    switch(speed)
    {
    case 1:	// 1:1
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
        bcm2835_gpio_write(M0, LOW);
		bcm2835_gpio_write(M1, LOW);
        break;
    case 2:	// 1:2
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_write(M0, HIGH);
        bcm2835_gpio_write(M1, LOW);
        break;
    case 3:	// 1:4
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_INPT);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
        bcm2835_gpio_write(M0, BCM2835_GPIO_PUD_OFF);
        bcm2835_gpio_write(M1, LOW);
        break;
    case 4:	// 1:8
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
        bcm2835_gpio_write(M0, LOW);
        bcm2835_gpio_write(M1, HIGH);
        break;
    case 5:	// 1:16
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
        bcm2835_gpio_write(M0, HIGH);
        bcm2835_gpio_write(M1, HIGH);
        break;
    case 6:	// 1:32
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_INPT);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_write(M0, BCM2835_GPIO_PUD_OFF);
        bcm2835_gpio_write(M1, HIGH);
        break;
    default:	// 1:1
        bcm2835_gpio_fsel(M0, BCM2835_GPIO_FSEL_OUTP);
		bcm2835_gpio_fsel(M1, BCM2835_GPIO_FSEL_OUTP);
        bcm2835_gpio_write(M0, LOW);
        bcm2835_gpio_write(M1, LOW);
        break;
    }
	return true;
}

 

Link to comment
Share on other sites

And rpi_focus.h

/*******************************************************************************
  Copyright(c) 2014 Radek Kaczorek  <rkaczorek AT gmail DOT com>

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License version 2 as published by the Free Software Foundation.
 .
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.
 .
 You should have received a copy of the GNU Library General Public License
 along with this library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.
*******************************************************************************/

#ifndef FOCUSRPI_H
#define FOCUSRPI_H

#include <indifocuser.h>

class FocusRpi : public INDI::Focuser
{
    protected:
    private:
        ISwitch FocusResetS[1];
        ISwitchVectorProperty FocusResetSP;
        
        ISwitch FocusParkingS[2];
        ISwitchVectorProperty FocusParkingSP;
 
		INumber FocusBacklashN[1];
		INumberVectorProperty FocusBacklashNP; 
    public:
        FocusRpi();
        virtual ~FocusRpi();

        const char *getDefaultName();

        virtual bool Connect();
        virtual bool Disconnect();
        virtual bool initProperties();
        virtual bool updateProperties();        
        void ISGetProperties (const char *dev);
        
        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
        virtual bool ISSnoopDevice(XMLEle *root);
        virtual bool saveConfigItems(FILE *fp);

		virtual IPState MoveFocuser(FocusDirection dir, int speed, int duration);
        virtual IPState MoveAbsFocuser(int ticks);
        virtual IPState MoveRelFocuser(FocusDirection dir, int ticks);
        virtual bool SetSpeed(int speed);
};

#endif

 

Link to comment
Share on other sites

Having read up on how the Ekos auto-focussing works, I'm not sure I want to use it in the way I was thinking.  I was thinking of using auto-focus when changing filters (because SLR camera lenses are not apochromatic far enough into the red end of the spectrum for astro imaging without re-focussing) but I'm not sure the data will be sufficient without it taking a long time.  The human eye is a lot better at determining focus than an electronic system and an alternative idea (which I've tried) is to measure the offset in focus steps between filters and then change focus by the pre-recorded amount when changing filters.

Link to comment
Share on other sites

Been looking into what I want to put on the RPi HAT to control my ASC.  The problem with the "logic level" power MOSFETs for heater control is that they are specified for a full +5v on the gate to switch on and the RPi logic is only 3.3v rather than 5v.  In that respect the Arduino Nano wins.  To control the heater from GPIO would need a transistor and a couple of resistors extra.

Link to comment
Share on other sites

I have a number of P channel power MOSFETs and can use one of those in conjunction with an NPN transistor and a few resistors to drive the heater - means the drive will still be logic 1 (3.3v) for on and logic 0 for off.

Heater Circuit 01.JPG

Link to comment
Share on other sites

I've been upgrading my desktop PC to Ubuntu 16.04 for the last couple of days and reinstalling everything I need. It now enables me to install the latest version of KStars/Ekos and it is much improved.

Basic installation is

1. Install Repository and update package lists

sudo apt-add-repository ppa:mutlaqja/ppa
sudo apt-get update

2. Install Indi Library and all 3rd party drivers

sudo apt-get install indi-full

3. Install Ekos & KStars

sudo apt-get install kstars-bleeding

4. Start KStars and select Ekos from the Tools menu

5. Setup a new Profile by clicking on the plus sign next to the Profile drop-down.

6. Add your devices

Screenshot from 2016-10-13 11-07-51.png

Make sure you enter the correct IP address of your Indi server (in my case it's the RPi3)

Note that you cant add the Astroberry Focuser here for some reason but if you have it running on your Indi server it will show up in the next steps.

Click Save.

7. Ensure the Indi Server is running on the remote device (RPi)

indiserver -m 100 -vv indi_celestron_gps indi_simulator_ccd indi_rpifocus

8. Connect to the remote Indi Server

Back in Ekos hit 'Start Indi' then 'Connect'. The Indi Control Panel should appear. This allows you to control the settings of your devices.

Screenshot from 2016-10-13 11-09-05.png

 

Also you will get extra tabs appearing in Ekos to control your devices.

Screenshot from 2016-10-13 11-23-07.png

 

I tried the auto-focus and it takes a simulated CCD picture (I have no camera attached at the moment) then moves the focuser around until it is in focus.

 

Screenshot from 2016-10-13 11-25-19.png

 

All looking good so far. I need to get the stepper controller off the breadboard and onto the RPi HAT but I need to have a play with the M0 & M1 signals first to see the best way of connecting them. The other possibility is to modify the Astroberry driver to use 3 GPIO lines to control the MS1,2,3 lines correctly on the A4988. This could be a temporary work-round until I create my own driver, or I could even feed it back to the driver writer as a possible enhancement.

 

  • Like 1
Link to comment
Share on other sites

So that's where you've been :D  Welcome back Dave :)  I've been out this morning.  Auto-focussing sounds interesting.  I was considering altering the Astroberry INDI driver to use the 3 MS lines too - shouldn't be all that difficult.  That would make the focuser work in the way Ekos expects.

I've nearly finished my all sky cam RPI HAT construction but not tested anything yet.  I'll post a photo or two later.  Not sure when - have a little repair to do on my observatory this afternoon!

Link to comment
Share on other sites

I've been monitoring the state of the GPIO lines that are supposed to feed M0 & M1 and they don't seem to change state during auto-focus (permanent low). That is unless they are doing it so fast I cant see it using an LED or DVM. I don't have an oscilloscope so can't monitor them with any accuracy.

Link to comment
Share on other sites

I've just done a quick text search through the Astroberry source code and the speed isn't set to anything other than 1:1 stepping.

pi@indiserver:~/software/astroberry-svn $ grep -r "SetSpeed" *
rpi_focus.cpp:	SetSpeed(1);
rpi_focus.cpp:bool FocusRpi::SetSpeed(int speed)
rpi_focus.h:        virtual bool SetSpeed(int speed);

 

Link to comment
Share on other sites

I thought as much :)  No problem then - just tie all 3 MS lines to Gnd.  My Arduino focuser uses half step mode and a step count of 5 to represent one focus step so that's 2.5x 1:1 stepping.  For my lens WF rig a slight increase in resolution would seem advantageous.

Link to comment
Share on other sites

Observatory repair completed :)  Bearings for fold-down flap/window - broken 3D printed plastic ones replaced with proper pillow block ball bearings.  Now having a rest...

Edited by Gina
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • 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.