Jump to content

Narrowband

Astro Projects

  • entries
    16
  • comments
    1,180
  • views
    6,307

Setting up a Raspberry Pi for Astro Imaging and Control - Ubuntu Mate


Gina

9,114 views

This is a tutorial explaining how to install the Ubuntu Mate operating system and astro software onto a micro SD card to use in a Raspberry Pi for astro imaging and control of the relevant hardware.

54 Comments


Recommended Comments



INTRODUCTION

Firstly, let me say that this tutorial, although similar to the previous one differs in certain very important ways as a result of the new operating system so please read all of it.  The previous Raspbian operating system has proved problematic with recent versions and the creator of the astro software I'm using recommends Ubuntu Mate.  I have copied some common parts and included information which is particularly relevant to those who have not read the previous edition.

This is a tutorial explaining how to install an operating system and software into a micro SD card to use in a Raspberry Pi for astro imaging and control of the relevant hardware.  The software to capture images, control camera cooling and other things such as the mount etc. is called INDI and provides a set of drivers to control all the hardware.

The Raspberry Pi will run in what is called "headless" mode - meaning that no human interfaces are directly connected to the RPi - instead the RPi is connected to the local area network (LAN) using either Ethernet (preferred for speed and reliability) or WiFi.  Everything is then controlled from indoors on a computer also connected to the LAN.  This computer is called a "client" and the Raspberry Pi a "server".

This tutorial will detail all the steps involved in installing the operating system and software - there are rather a lot of them, hence the need for a tutorial.  I believe that anyone with some knowledge of computers should be capable of following these steps and setting up a working Linux based astro imaging system.  The Raspberry Pi can be put on the pier (or tripod) or even directly on the telescope mounting and would replace a laptop for instance, reducing the use of long cables etc.

Unfortunately, unlike with Raspbian, using Ubuntu Mate involves using a monitor, keyboard and mouse (or trackball) in order to set up the operating system and enable remote control before the RPi can be used headless in the observatory or on a tripod.

  • Like 1
Link to comment

Installing the Operating System and Astro software

The Raspberry Pi uses a micro SD card as its main drive and this behaves the same as the hard drive on a computer except that this card can be removed and data read from it or written to it.  In fact the way the operating system is installed on it requires it to be out of the RPi.  This tutorial will describe how the operating system is written to the card, the system set up with computer name, user name and password and then further software installed to permit remote control via LAN and the astro software to capture images and control the hardware such as filter wheel and mount.  You need an SD card reader attached to you computer.

First job is to download the operating system on the main computer and write it to the micro SD card. Go to the Ubuntu MATE download page,  choose the Raspberry Pi version (takes two clicks) and download it.

5a14839f05cfe_UbuntuMate01.thumb.png.625b9d7935e943aab42934f1cbf9589f.png

 

Next is to unzip it and write the image to the micro SD card.  I am now using Etcher for this as it works well with Linux (my main PC uses Linux Mint).  This unpacks and writes the OS to the card in one go.  Plug card into reader (with adapter if required), run Etcher and select the micro SD card - careful here not to select you HD or other device.  Also select the downloaded file.  Set Etcher going and a few minutes later the OS is written to the card.

There is a script that has been written for installing the INDI drivers onto the card in the RPi that covers what we are trying to do.  This is AstroPi3 and pretty much does it all.  The instructions given repeat what I have written above.  The lines of code can be copied and pasted from the web page into a Terminal window on the RPi.  Applications > System Tools > MATE Terminal.  Use Firefox on the RPi to go to the AstroPi3 page and copy/paste each command line to the Terminal window.  Hint, 3 clicks selects the whole line for copying.

The script installs INDI and a few other items of astro software but you don't have to accept it all if you don't want it.  The script may be edited to comment out unwanted items but you need to be careful and know what you're doing though "it's not rocket science" :D  It also turns on SSH so that further command lines can be added from the main PC through its Terminal window and SSH.  At this time the human interfaces can be disconnected from the RPi.

With this script you end up with a usable system that will capture images and control most of the astro equipment on the market.  Controlling DIY equipment is another matter and one I'm looking into.  The script takes an hour or more to run and has a few y/n responses needed.

One other point :- I'm using an extra RPi for setting up the micro SD card that will then go into the RPi in my all sky camera (or other imaging rig).  So the working RPi doesn't need to have all the human interface bits plugged in and that means the RPi card can fit into a smaller box - as long as the SD card is accessible.

That's it for the standard devices, the next section will deal with adding 3rd party drivers.

Edited by Gina
  • Like 1
Link to comment

there is some good stuff in the links. I have Ubuntu on a spare laptop which I have played with and have programmed PIC processors. I will follow this with a view to having a go as the kit does not look too expensive.

look forward to the next instalment

  • Like 1
Link to comment

"With this script you end up with a usable system that will capture images and control most of the astro equipment on the market." - well so long as you don't use a DSLR for long exposures (> 20secs) and its a Canon (some work many don't). Indi project has made progress but with regards to Canon DSLR control its still very backward/inconsistent when compared to Windows/Apple.

A pity really because Ascom/Eqmod (i.e. Microsoft ) are sill living in the stone age with serial interfaces on a single Microsoft PC:hiding:- I use them before you moan or shout at me! 

Oh,suggestion, try using CDC(using Indi connection via CDC telescope set up) instead of KSTARS on Windows (no need for VM or 64bit) runs faster and the Indi interface is more logically laid out - you will still need Indiserver running on RPI3 to control CCD/Mount etc and you will still have the problems but you get them faster LOL

Oh and watch out Ubuntu Mate 16.04 users on older laptops - it seems to cause over heating and then shuts itself down - problems with fan control it seems.

I will climb back under my rock till next Xmas .

 

  • Thanks 1
Link to comment

Oops - seems I haven't finished this.  I've had a break from astro imaging but plan to get back to it this coming autumn so will probably have information to add.

Link to comment
Gina

Posted (edited)

I expect to be adding to this blog shortly as I shall be building a new astro imaging control system from scratch and including installing 3rd party drivers and editing the source code to alter and/or add features.  I have a spare Raspberry Pi 3B and an 8GB micro SD card.  For setting up I have a spare keyboard, trackball and a small TV set I can use as a monitor using HDMI.

Edited by Gina
  • Like 1
Link to comment
Gina

Posted (edited)

I have installed Ubuntu MATE and followed the instructions to run the AstroPi3 script.  At this point I believe the INDI drivers and some other astro software has been installed. 

SSH has been enabled so that now the RPi can be accessed remotely from Terminal.  eg. ssh gina@rpi where gina is my user name and rpi is the computer name as set up during the Ubuntu MATE installation.

Installing 3rd Party Drivers

Next step is to attempt installing the Astroberry drivers.  The package contains four drivers of which I shall use two, with the source code modified to suit my needs.

Quote

This package provides the INDI drivers for Raspberry Pi devices:
* Astroberry Focuser - stepper motor driver with absolute and relative position capabilities and autofocus with INDI client such as KStars and Ekos
* Astroberry GPS - GPS driver for easy scope location and UTC time setting
* Astroberry AltIMU - accelerometer, magnetometer, gyro, atmospheric pressure sensor driver
* Astroberry Board - power switch board allowing for remote powering on/off up to 4 devices and monitor system parameters

The drivers I'm using are for focussing and a modified version of the Astroberry Board to provide ON/OFF controls for such things as dew heaters.

Edited by Gina
Link to comment
Gina

Posted (edited)

Before the C++ source code can be compiled we need to install cmake.

sudo apt install cmake

 

Edited by Gina
Link to comment

To avoid having to install extra packages to support the Astroberry GPS and AltIMU I shall edit the instructions file for the C++ compilations.  This is called CMakeLists.txt and is in the astroberry-diy directory.  To make editing easier I take the micro SD card out of the RPi and put it in my main machine and use the GUI editor.  As supplied the CMakeLists.txt is this :-

cmake_minimum_required(VERSION 2.4.7)

if(COMMAND cmake_policy)
    cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)

PROJECT(astroberry CXX C)
include(ExternalProject)

set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/")
set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")


find_package(INDI REQUIRED)

#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )

include_directories( ${CMAKE_CURRENT_BINARY_DIR})
include_directories( ${CMAKE_CURRENT_SOURCE_DIR})
include_directories( ${INDI_INCLUDE_DIR})

include_directories(${CMAKE_SOURCE_DIR}/libs/bcm2835-1.52/src)

add_library(bcm2835 STATIC IMPORTED)
set_property(TARGET bcm2835 PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/bcm2835-1.52/src/libbcm2835.a)
add_dependencies(bcm2835 libbcm2835)

################ libbcm2835 ################

ExternalProject_Add(libbcm2835
    URL "http://www.airspayce.com/mikem/bcm2835/bcm2835-1.52.tar.gz"
    SOURCE_DIR ${CMAKE_SOURCE_DIR}/libs/bcm2835-1.52
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/bcm2835-1.52
    CONFIGURE_COMMAND ./configure
    BUILD_COMMAND ${MAKE}
    INSTALL_COMMAND ""
    BUILD_IN_SOURCE 1
)


################ Astroberry Board ################

set(indi_rpibrd_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/rpi_brd.cpp
   )

add_executable(indi_rpibrd ${indi_rpibrd_SRCS})
target_link_libraries(indi_rpibrd indidriver bcm2835)
install(TARGETS indi_rpibrd RUNTIME DESTINATION bin )
install(FILES indi_rpibrd.xml DESTINATION ${INDI_DATA_DIR})

################ Astroberry AltIMU ################

set(indi_rpialtimu_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/rpi_altimu.cpp
   )

add_executable(indi_rpialtimu ${indi_rpialtimu_SRCS})
target_link_libraries(indi_rpialtimu indidriver RTIMULib)
install(TARGETS indi_rpialtimu RUNTIME DESTINATION bin )
install(FILES indi_rpialtimu.xml DESTINATION ${INDI_DATA_DIR})

################ Astroberry GPS ################

set(indi_rpigps_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/rpi_gps.cpp
   )

add_executable(indi_rpigps ${indi_rpigps_SRCS})
target_link_libraries(indi_rpigps indidriver gps nova)
install(TARGETS indi_rpigps RUNTIME DESTINATION bin )
install(FILES indi_rpigps.xml DESTINATION ${INDI_DATA_DIR})

################ Astroberry Focuser ################

set(indi_rpifocus_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/rpi_focus.cpp
   )

add_executable(indi_rpifocus ${indi_rpifocus_SRCS})
target_link_libraries(indi_rpifocus indidriver bcm2835)
install(TARGETS indi_rpifocus RUNTIME DESTINATION bin )
install(FILES indi_rpifocus.xml DESTINATION ${INDI_DATA_DIR})

We need to remove the sections for the GPS and AltIMU :-

cmake_minimum_required(VERSION 2.4.7)

if(COMMAND cmake_policy)
    cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)

PROJECT(astroberry CXX C)
include(ExternalProject)

set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/")
set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")


find_package(INDI REQUIRED)

#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )

include_directories( ${CMAKE_CURRENT_BINARY_DIR})
include_directories( ${CMAKE_CURRENT_SOURCE_DIR})
include_directories( ${INDI_INCLUDE_DIR})

include_directories(${CMAKE_SOURCE_DIR}/libs/bcm2835-1.52/src)

add_library(bcm2835 STATIC IMPORTED)
set_property(TARGET bcm2835 PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/bcm2835-1.52/src/libbcm2835.a)
add_dependencies(bcm2835 libbcm2835)

################ libbcm2835 ################

ExternalProject_Add(libbcm2835
    URL "http://www.airspayce.com/mikem/bcm2835/bcm2835-1.52.tar.gz"
    SOURCE_DIR ${CMAKE_SOURCE_DIR}/libs/bcm2835-1.52
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/bcm2835-1.52
    CONFIGURE_COMMAND ./configure
    BUILD_COMMAND ${MAKE}
    INSTALL_COMMAND ""
    BUILD_IN_SOURCE 1
)


################ Astroberry Board ################

set(indi_rpibrd_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/rpi_brd.cpp
   )

add_executable(indi_rpibrd ${indi_rpibrd_SRCS})
target_link_libraries(indi_rpibrd indidriver bcm2835)
install(TARGETS indi_rpibrd RUNTIME DESTINATION bin )
install(FILES indi_rpibrd.xml DESTINATION ${INDI_DATA_DIR})

################ Astroberry AltIMU ################

################ Astroberry GPS ################

############### Astroberry Focuser ################

set(indi_rpifocus_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/rpi_focus.cpp
   )

add_executable(indi_rpifocus ${indi_rpifocus_SRCS})
target_link_libraries(indi_rpifocus indidriver bcm2835)
install(TARGETS indi_rpifocus RUNTIME DESTINATION bin )
install(FILES indi_rpifocus.xml DESTINATION ${INDI_DATA_DIR})

After editing the file is saved back to the micro SD card (may be obvious but can be forgotten).

At this point the source code will compile but I am using a different stepper motor and driver module from the one for which the Astroberry Focuser code was written.  I will cover this in the next post.

Link to comment

Astroberry Focuser code edited to suit the NEMA range of stepper motors and A4988 driver module.  These use a different method of speed control.  The speed is now set in the hardware to suit the focuser mechanics (gearing or belt reduction).  Testing has shown the KStars/Ekos/INDI auto-focus routine doesn't use speed control hence the speed control has been commented out.  (I've left the original code in comments in case anyone is interested in that information.)

/*******************************************************************************
  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.
*******************************************************************************/

/*******************************************************************************
 Modified by Gina for NEMA range of stepper motors and A4988 driver module.
 Remote focussing works fine without speed control and the speed control code
 has been commented out.  Appropriate speed is set in hardware to suit focuser.
*******************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <memory>
#include <bcm2835.h>
#include <string.h>

#include "rpi_focus.h"

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

// 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();

    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);

    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)
{
    return INDI::Focuser::ISSnoopDevice(root);
}

bool FocusRpi::saveConfigItems(FILE *fp)
{
    IUSaveConfigNumber(fp, &FocusRelPosNP);
    IUSaveConfigNumber(fp, &PresetNP);
    IUSaveConfigNumber(fp, &FocusBacklashNP);
	IUSaveConfigSwitch(fp, &FocusParkingSP);

    if ( FocusParkingS[0].s == ISS_ON )
		IUSaveConfigNumber(fp, &FocusAbsPosNP);

    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

The Astroberry Board driver as supplied is designed to control a PCB with 4 relays on it for switching power supplies to other equipment but can be used for anything requiring ON/OFF control for up to 4 lines.  I use it to control a dew heater and on my All Sky Camera I also have a Peltier TEC cooler which is controlled by the Astroberry Board driver.  For such specialised applications it's useful to change the labels on the controls displayed by Ekos and this is relatively easy in the source code.

First though having saved my edited files back to the micro SD card I shall put it back in the RPi and run the compiler and installer sequence of commands.

Link to comment
Gina

Posted (edited)

SSH has stopped working over WiFi.

gina@Mint-Desktop ~ $ ssh gina@rpi
ssh: connect to host rpi port 22: No route to host
gina@Mint-Desktop ~ $ 

 

Edited by Gina
Link to comment
Gina

Posted (edited)

Update :- SSH is working with cable so it's WiFi that's failed.

Trying compile and install over cable using these steps :-

cd astroberry-diy/build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
sudo make install
sudo reboot

Proceeded fine up to the make when the focuser compilation failed so that needs looking at.  With no hardware connected I can revert to the original and test with that.

Edited by Gina
Link to comment

Copied the original file back to the micro SD card and put it back into the RPi but the compiling error still occurs :icon_scratch:

Think I shall leave this and do something else...

Link to comment

Well...  WiFi isn't working and compiling the original files isn't working so maybe it's time to start again from square one!

Link to comment
Gina

Posted (edited)

OK - from square one again...  Wrote Ubuntu MATE to card, set parameters in config.txt as described in the AstroPi3 instructions and ran the script .  What seemed like hours later the script had finished.  Rebooted the system as instructed.  WiFi is working and so is SSH over WiFi.  Next task is to install the Astroberry 3rd party drivers.  Think I might back-up the card contents first though.  And having got this far successfully I think I'll call it a day.

Edited by Gina
Link to comment

Backing up the card contents then it's back to trying to install the Astroberry 3rd part drivers.

Link to comment

Backed up and back in RPi ready to load, compile and install Astroberry drivers.  First then to install cmake :-

sudo apt install cmake

Done - here's the Terminal

gina@asc2:~$ sudo apt install cmake
[sudo] password for gina: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  cmake-data libjsoncpp1
Suggested packages:
  codeblocks eclipse ninja-build
The following NEW packages will be installed:
  cmake cmake-data libjsoncpp1
0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded.
Need to get 3,502 kB of archives.
After this operation, 15.0 MB of additional disk space will be used.
Do you want to continue? [Y/n] 
Get:1 http://ports.ubuntu.com xenial-updates/main armhf cmake-data all 3.5.1-1ubuntu3 [1,121 kB]
Get:2 http://ports.ubuntu.com xenial/main armhf libjsoncpp1 armhf 1.7.2-1 [65.4 kB]
Get:3 http://ports.ubuntu.com xenial-updates/main armhf cmake armhf 3.5.1-1ubuntu3 [2,316 kB]
Fetched 3,502 kB in 0s (4,756 kB/s)
Selecting previously unselected package cmake-data.
(Reading database ... 208195 files and directories currently installed.)
Preparing to unpack .../cmake-data_3.5.1-1ubuntu3_all.deb ...
Unpacking cmake-data (3.5.1-1ubuntu3) ...
Selecting previously unselected package libjsoncpp1:armhf.
Preparing to unpack .../libjsoncpp1_1.7.2-1_armhf.deb ...
Unpacking libjsoncpp1:armhf (1.7.2-1) ...
Selecting previously unselected package cmake.
Preparing to unpack .../cmake_3.5.1-1ubuntu3_armhf.deb ...
Unpacking cmake (3.5.1-1ubuntu3) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
Setting up cmake-data (3.5.1-1ubuntu3) ...
Setting up libjsoncpp1:armhf (1.7.2-1) ...
Setting up cmake (3.5.1-1ubuntu3) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
gina@asc2:~$ 

Next to load the Astroberry package

git clone https://github.com/rkaczorek/astroberry-diy.git

In Terminal

gina@asc2:~$ git clone https://github.com/rkaczorek/astroberry-diy.git
Cloning into 'astroberry-diy'...
remote: Counting objects: 160, done.
remote: Total 160 (delta 0), reused 0 (delta 0), pack-reused 160
Receiving objects: 100% (160/160), 79.47 KiB | 0 bytes/s, done.
Resolving deltas: 100% (92/92), done.
Checking connectivity... done.
gina@asc2:~$ 

Now as mentioned above the commands to compile the Astroberry GPS and AltIMU need to be removed from the CMakeLists.txt file.  To make editing easier I take the micro SD card out of the RPi and put it in my main machine and use the GUI editor.

Link to comment

CMakeLists.txt file edited to remove the commands to compile the unwanted drivers.  Here a screenshot of the editor showing the relevant section.  Only code for the AltIMU and GPS drivers has been removed - nothing else touched.
547986577_Screenshotfrom2018-06-2911-59-56.thumb.png.bd228308198d0ccd36f79d9b6017a049.png

Link to comment
Gina

Posted (edited)

Card Ejected from Mint and put back into RPi.  RPi powered up and Terminal connected via SSH.  viz

ssh gina@asc2

Now to try compiling using these commands :-

cd astroberry-diy
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
sudo make install
sudo reboot

 

Edited by Gina
Link to comment

AARRGGHH!!!  Still getting the error in the focuser driver compilation.  :icon_scratch:

Link to comment

I think the next step is to compare the source files for the focuser driver that work and the ones that don't work.

Link to comment

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.