Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Reputation Activity

  1. Like
    tripwire reacted to monsonite in SIMPL - A Tiny Language for MSP430   
    Thanks for that useful update.
    My FR2433 samples have arrived from the USA in record time, and I am now just awaiting the pcbs for the 20 pin module.
    I am planning two sizes of module, a 20 pin 0.3" DIL and a 40 Pin 0.6" DIL.   The larger of which will support either 16K or 64K of FRAM:
    F 20-16      20 pin, 16K FRAM   - uses MSP430FR2433  (or FR25xx, FR26xx)
    F 40-16      40 pin, 16K FRAM  - Uses MSP430FR5739 or equiv.
    F 40-64      40 pin, 64K FRAM  - Uses MSP430FR58xx or FR59xx.
    All modules have an 8 pin SPI memory footprint. This allows either a 23K256 (32Kx8) or 23LC1024  (128Kx8) SRAM  or any of the Cypress or Fujitsu FRAM parts up to the 256Kx8 to be fitted - depending on budget.
    The F20 is intended to plug in as a replacement for the G2553.   The F40 is designed to have the same pin out as an ATmega1284 - this is so it can be plugged into various ATmega boards - for an immediate x4 boost in performance.
  2. Like
    tripwire reacted to jazz in SIMPL - A Tiny Language for MSP430   
    G2 LP can be used as BSL hardware for FR2xx/4xx www.ti.com/cn/lit/pdf/slaa535
    BTW, FR2xx/4xx family has CPUX2, with 20-bit registers, and can execute CPUX2 20-bit address instructions in one cycle. It also has mailbox. Same as FR5xx/6xx.
  3. Like
    tripwire reacted to RogueGeek in Launchpad Timer Reference Oscillator   
    I'm working on building a speed controller for a belt grinder and I'm using a G2553 for the controller.  Since the speed of the motor will need to vary between 1000-8000 RPM, the 32.768Khz clock was too slow and the DCO was drifting too much and causing the RPM to vary by several hundred counts even when the motor was running at a constant stable speed. This in turn caused the PID loop to act really weird and I could not hold a stable speed.  What I needed was a stable reference oscillator to use for sensing the RPM of the drive motor. 
    Being stubborn, I wanted to do this with only a single G2553 cpu and since the 2553 isn't spec'd to use a high freq crystal I went looking for an alternate way to provide a reference for the timers.  I was quite happy to discover that P1.0 can be configured as an input for an external timer reference. Thus the "Launchpad Timer Reference Oscillator" was born. 
    In my application I'm using a 16MHz oscillator, but any speed could be used to fit the given application.

    It is a small 0.3" x 1" pcb with an Abracon oscillator, a 0.1uF cap., and connectors.
    It only took a minor code change to have the Timer use the external reference and so far it seems to have resolved my timing issues.
    While this is without a doubt the most simple PCB I think I have ever designed, it just may turn out to be one of the most useful.
    I will definitely be including an external reference oscillator in any of my future projects that need very accurate time references.
    Here it is in action.

    thanks for looking
  4. Like
    tripwire reacted to RogueGeek in Sine Wave Generator using PWM like a class D amplifier.   
    About a year or so ago, I quit working on a project which would generate the 1200 baud audio tones for an AFSK Amateur Radio system.
    Due to real life getting in the way, I never finished it.  I got it to generate the audio tones but never fully implemented the ascii data input handling.
    This general design isn't anything new, it has been done before on other platforms and it is quite likely someone has done it on the MSP.
    It was my first real development effort using Timers and was a good learning experience. 
    I figured it was time to post the code in case all or part of it might be useful to someone.   USE AT YOUR OWN RISK.
    Essentially this code implements a software driven class D amplifier using an MSP430G2553 to generate either a 1200Hz  or  2200 Hz sine wave using PWM.
    The PWM output is run through a simple low pass filter to get the clean sine wave audio tones.
    This uses all of the available timers on the G2553.
    TA1 is the PWM generator running at 500Khz
    TA0 is the modulator.
    WDT is used as an interval timer to clock the ascii data into the modulator at 1200 buad (this is where I stopped working)
    The TA0 modulator steps through the wave table and updates the TA1 PWM duty cycle setting it to the value in the wave table.  TA1CCR1  = SineTable[sinePosition];
    This runs in a continuous loop. The rate at which TA0 steps through the table is the MARK and SPACE values.  This rotating PWM duty cycle is what generates the 1200Hz or 2200Hz sine wave.
    The 500Khz PWM frequency is filtered out by the low pass filter.
    The NOT WORKING parts.
    Basically I quit shortly after starting on the ASCII input handling. The idea was that the WDT loop would set TA0 to MARK or SPACE depending on the ASCII character to be sent.
    I was in the process of trying to implement a FIFO buffer when I stopped developing the code.
    I hope someone finds this useful. 
    WARNING:  The code you are about to view most likely breaks every known rule for good software design.
    It may use magic numbers, variables named X or Y, have little of no care for memory management, or have numerous other or unknown issues.
    This was R&D code and I never really meant for it to be seen by anyone other than myself.
  5. Like
    tripwire reacted to Druzyek in Stupidest Thing you had to Troubleshoot?   
    I've have several projects with a 5 pin header for the 6 pin FT232 cable since none of the projects use the 6th pin. One time I plugged the header into pins 2-6 of the FT232 cable instead of 1-5 and my launchpad died :S Also, took a while to get my first MCP23S17 I/O expander to work since the datasheet incorrectly lists the RESET pin as an output, not an input.
  6. Like
    tripwire reacted to spirilis in double vs float in TM4C123   
    Float is handled with native hardware FPU instructions for speed.  Double is handled in software (not sure if it's capable of using the FPU but I think not).  Float would be much faster.
  7. Like
    tripwire reacted to monsonite in A Tiny Plug In Computer using MSP430FR2xxx devices   
    Last week, I introduced a tiny language, called SIMPL,  I have been working with for a while. Now I'd like to introduce some hardware - that I hinted upon last week.

    ChipStick is possibly one of the smaller dev boards you may encounter - it's intended to plug into a 20 pin DIL socket - which makes it both breadboard and Launchpad friendly.
    At it's heart is one of the new MSP430FR2xxx series devices with 15.5kbytes of FRAM and 4Kbytes of RAM.
    These controllers come in a tiny 4mm square 24 pin QFN surface mount package, making them a bit awkward to prototype with - so that's why the idea of ChipStick was developed - a small carrier pcb which converts the SMT part into a plug-in DIL 20 package.
    ChipStick also comes with its own programmer section - based on the low cost CH340G USB to serial converter IC. This allows communications between the IC and a laptop, and also allows it to be programmed serially using the uart based BSL programming option.
    The programming section is detachable - so you can have just the 20 pin DIL module if you want to go extra small.  
    In this format the board is small enough to fit inside a 2x4 LEGO block!

    In addition to the MSP430 there is also 32K x 8 bytes of external SPI SRAM or FRAM (depending on your application). The MSP430FR2xxx series have 3 communication interfaces and the 25xx and 26xx parts have capacitive touch capability too.
    One of the aims of ChipStick is to teach electronics and computer science.  Whilst it is not the fastest device the external memory allows virtual machines to be investigated and the high speed SPI allows shift registers to be used for extending the I/O - for driving LED arrays or stepper motors or whatever peripheral electronics you wish.
    ChipStick may be programmed using Energia, CCS or a high level language such as Forth, including MECRISP, 4E4th or Amforth.
    My inspiration came from another small computer, the PDP5 from 53 years ago.
    ChipStick offers about the same computing resources as the PDP5, but for $5 not the $50,000 the PDP5 cost in 1963!
    The first batch of ChipStick pcbs have been ordered. After Easter I should have something up and running, at which point the EagleCAD files will be made available.
  8. Like
    tripwire reacted to Fmilburn in [Energia Library] Hardware Counter Library for MSP430   
    I don't have a FR4133 so can't test the code but try this:
    #elif defined(__MSP430FR4133__) enum CL_TIMER_t { CL_TimerA0, // FR4133 P1.5, pin 11 on LaunchPad CL_TimerA1, // FR4133 P8.2, pin 9 on LaunchPad }; // clk pin setup for each supported timer #define CL_TA0CLK_PIN_SETUP { P1DIR &= ~BIT5; P1SEL0 &= ~BIT5; P1SEL1 |= BIT5; } #define CL_TA1CLK_PIN_SETUP { P8DIR &= ~BIT2; P8SEL0 &= ~BIT2; P8SEL1 |= BIT2; } Insert it into CounterLib_t.h just before the section at line 72 with the following code
    #else #error 1) This microcontroller is not supported by CounterLib #endif If, in my haste, I did this correctly it should work with the examples on Pin 11 of the FR4133.  Please report back whether or not this works for you.
  9. Like
    tripwire reacted to greeeg in Have you experienced a chilling effect?   
    I've been around on the forums for awhile now. I really enjoy seeing other peoples projects. Especially how they go about solving problems that I would hove done differently. I think there is great value in that. That's why I try to post about my projects too.
    I'm in my final year of my EE degree. And information I've gained from this forum has definitely influenced my thought pattern for the better when approaching new problems.
    But also unfortunately there are people who upon seeing the same project will just be thinking of ways they could profit from others work. There might not actually be too many of these people, but it only takes one to make you think about this stuff next time you think of sharing a project, which is a real shame.
    I'll continue to share my hobby projects, A factor that stops me posting more is that not all of my projects contain TI micro's so I don't feel it's relevant to post here. For example I'm currently working on a DIY PnP.
    I've also noticed alot more students asking for help with their projects. (assessed projects) (sometimes even capstone projects!) And they typically just want the answer, sometimes don't acknowledge users who try to help. This doesn't look good for the forums. But I'm not sure what the solution is.
  10. Like
    tripwire reacted to Fmilburn in Have you experienced a chilling effect?   
    I got involved with this community essentially knowing nothing about microcontrollers or C/C++ when I retired as an engineering manager with a mechanical background (in Calgary by the way - one of my  favorite places).  Microcontrollers were  just something that caught my interest after viewing a TED video on Arduino.  And on average, the quality of the projects and the help / discussion just seemed to be on a higher level on 43oh than with the Arduino crowd.
    For me, learning this stuff beyond the superficial on my own outside of a classroom setting and without colleagues is hard.  But it has been rewarding and a great experience.  And I have learned something from each of you who have posted above.  So, my thanks to you.
    This is just a hobby for me, and it is unlikely anyone developing a commercial product is going to gain much from my advice .  Having said that, I try to give as much as I take. And a good way to learn and hopefully help others has been to read the problems others are having and see if I can solve them.  For those who would like to continue getting that kind of help, here are some tips:
    Don't abuse the goodwill of 43oh members in the manner described above Search and make a real effort to solve it yourself first Post sufficient information for someone to help solve the problem but be as succinct as possible and don't post a 100 lines of code Use the thanks button when someone helps - really, how much effort does that take?  Somebody just spent personal time to help you for free. When your problem is solved, consider editing your first post and put [sOLVED] in the title, or at least follow up with a post that you finally got it to work and how.  The next person with that problem will thank you. My son-in-law has a masters in EE and is now a patent attorney.  I asked him a while back about the practicalities of protecting intellectual property for the small guy or hobbyist.  My interpretation of that conversation was that unless you have money and/or time it is difficult.  A shame, the result is that you must do something like Spirilis suggests and carefully consider/tier responses, help, and what is revealed. 
     I appreciate the help past and future, and enjoy hearing about the projects. But, I also understand the sentiments expressed above and don't want to see livelihoods threatened.
  11. Like
    tripwire reacted to monsonite in SIMPL - A Tiny Language for MSP430   
    Hello All
    My MSP430FR4133 Launchpads turned up this morning and it was quite quick and easy to port SIMPL across to it - from previously on the MSP430G2533
    I have included the code below.
    The UART is running at 125000 Baud -  a simple binary division of the 8MHz clock.   I use Termite or Terraterm - which will handle these non standard baudrates.
    The SPI RAM is connected to USCB0   - see this blogpost for preliminary details.
    On the '4133 Launchpad the following connections are needed
    MOSI           P5.2
    MISO           P5.3
    SCLK           P5.1
    /RAM_CS    P8.0
    I've got the display to display integers <100, with some rather dirty code!
    In the future I like the look of the new low cost, low pin-out  FRAM based   FR24xx, FR25xx and FR26xx series as potential targets for SIMPL
    // SIMPLEX 2_MSP430FR4133_5 // - inspired by Txtzyme Nano Interpreter - an original idea by Ward Cunningham // An on going Neo-Retro Computing Mission! // Ken Boak March 9th 2016 // SIMPL Interpreter for MSP430FR4133 Launchpad // This version adds 23K256 32Kx8 external SPI RAM, plus hex-dump utlity // With addition of timing routines and other debug // MSP430FR4133 UART, SPI and LCD suport Routines // - codesize is now 4167 bytes // This version for FRAM based MSP430 with MSP430FR4133 Launchpad compiled using Energia // Note - serial uart on P1.1 and P1.2 is running at odd-baud of 100,000 bits/s - to be investigated // This version includes the t and v functions to determine timing tests - note millis is running at 16 times speed! // Any time entered for m or u is multiplied by 16 // Any time printed out from b or c id divided by 16! // There is a debug pin on P1.0 (Green LED) which allows scope probe attachment to confirm times // RAM connections /*         +------U------+ P8.0 /CE    |   23K256    | 3V3 P5.2  MISO   |             | HOLD - pull up to 3V3  NC |             | SCK - P5.1   0V   |             | MOSI - P5.2         +-------------+ */ // Timing // 1,000,000 empty loops in 2.4uS per iteration // 100,000,000 empty loops in 2.4uS per iteration #include <MSP430FR4133.h> #define RXD BIT1 // Receive Data (RXD) at P1.1 #define TXD BIT2 // Transmit Data (TXD) at P1.2 #define RED 0x20 // Red LED is on Bit 6 #define GREEN 0x01 // Green LED is on Bit 0 //#define SS_PIN BIT4 // CS , active low #define SS_PIN BIT0 // CS , active low Port 8.0 #define DEBUG_PIN BIT0 // toggle on and off marking time to write #define DUMMY_BYTE 0xFF // byte we send when we just want to read slave data //#define ssSelect P1OUT &= ~SS_PIN //#define ssDeselect P1OUT |= SS_PIN #define ssSelect P8OUT &= ~SS_PIN #define ssDeselect P8OUT |= SS_PIN #define delay_1ms __delay_cycles(16000) #define bufRead(addr) (*(unsigned char *)(addr)) #define bufWrite(addr, (*(unsigned char *)(addr) = () #define bit0 0x01 // 1 #define bit1 0x02 // 2 #define bit2 0x04 // 4 #define bit3 0x08 // 8 #define bit4 0x10 // 16 #define bit5 0x20 // 32 #define bit6 0x40 // 64 #define bit7 0x80 // 128 #define SR_WRITE_STATUS 0x01 #define SR_WRITE 0x02 #define SR_READ 0x03 #define SR_READ_STATUS 0x05 #define BYTES_TO_STREAM 1024 // should be less <= 32768 #define PATTERN_BYTE_VALUE 65 //--------------------------------------------------------------------------------- // LCD defines #define pos1 4 // Digit A1 - L4 #define pos2 6 // Digit A2 - L6 #define pos3 8 // Digit A3 - L8 #define pos4 10 // Digit A4 - L10 #define pos5 2 // Digit A5 - L2 #define pos6 18 // Digit A6 - L18 const char digit[96] = // Array to hold digits, upper case alpha and punctuation { 0xFC, // "0" 0x60, // "1" 0xDB, // "2" 0xF3, // "3" 0x67, // "4" 0xB7, // "5" 0xBF, // "6" 0xE4, // "7" 0xFF, // "8" 0xF7 // "9" }; //--------------------------------------------------------------------------------- static inline uint8_t RWData(uint8_t value); int spi_rx_data = 0 ; //----------------------------------------------------------------- // This character array is used to hold the User's words - on the '2553 we only have 512 bytes of RAM char array[6][32] = { {"_Hello World, welcome to SIMPL_"}, {"_Mary had a Little Lamb_"}, {"_This is a test message_"}, {"_Hickory, Dickory Dock_"}, {"_twas brillig slithy toves_"}, {"11{kp_ Green Bottles_}"} }; char buf[64]; // Buffer to hold users keyboard entry char num_buf[11]; // long enough to hold a 32 bit long char block_array[33]; // Used to transfer bytes from external RAM and execute x-code // int a = 0; // integer variables a,b,c,d // int b = 0; // int c = 0; // int d = 6; // d is used to denote the digital port pin for I/O operations unsigned long x = 0; // Three gen purpose variables for stack & math operations unsigned long y = 0; unsigned int z = 0; unsigned int ADC_value=0; int hex_value = 0; int dec_value = 0; int decimal_value = 0; char ha = 0; char hex_char; unsigned char in_byte; int len = 32; // the max length of a User word int length = 0; // number of bytes to red/write to SRAM int address = 0 ; // starting address of RAM R/W streamms int RAM_byte =0; // contents of RAM at given location long old_millis=0; long new_millis=0; unsigned long time = 0; char name; char* parray; char* px_array; char* addr; char mode = 0x41; // Sequential mode for SRAM unsigned int num = 0; unsigned int num_val = 0; int j; /* //--------------------------------------------------------------------- // Initialise the USCI B for Master Mode SPI //--------------------------------------------------------------------- // recommended procedure: set UCSWRST, configure USCI, configure ports, activate //--------------------------------------------------------------------- void spi_init(void) { //--------------------------------------------------------------------- // Configure the Clock for 16 MHz BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; //--------------------------------------------------------------------- // Set UCSWRST UCB0CTL1 = UCSWRST; //--------------------------------------------------------------------- // Configure USCI B0 UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 2; // 8 MHz SPI-CLK UCB0BR1 = 0; //UCB0MCTL = 0; //--------------------------------------------------------------------- // Configure Ports P1SEL |= BIT5 + BIT6 + BIT7; P1SEL2 |= BIT5 + BIT6 + BIT7; P1DIR |= BIT0 + BIT4 + BIT5 | BIT7; //--------------------------------------------------------------------- // activate UCB0CTL1 &= ~UCSWRST; } */ //-------------------------------------------------------------------------------- // SPI Initialisation for MSP430FR4133 LaunchPad //-------------------------------------------------------------------------------- // P5.3 MISO // P5.2 MOSI // P5.1 SCLK // P8.0 /RAM_CS void spi_init_4133() { // Configure GPIO P8DIR |= BIT0; // For /RAM_CS P5SEL0 |= BIT1 | BIT2 | BIT3; // SCLK, MISO, MOSI pins // Configure USCI_B0 UCB0CTLW0 |= UCSWRST; // **Put state machine in reset** UCB0CTLW0 |= UCMST|UCSYNC|UCCKPH|UCMSB; // 3-pin, 8-bit SPI master // Clock polarity low, MSB UCB0CTLW0 |= UCSSEL_2 ; // SMCLK UCB0BR0 = 0x01; // /2,fBitClock = fBRCLK/(UCBRx+1). UCB0BR1 = 0; // UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine** } //-------------------------------------------------------------------------------- // 23K256 Serial Ram functions //-------------------------------------------------------------------------------- uint8_t SR_getMode(void) { // Read the Mode of the 23K256 ssSelect; // select RWData(SR_READ_STATUS); // 0x05 uint8_t mode = RWData(DUMMY_BYTE); ssDeselect; // de-select return mode; } void SR_setMode(uint8_t mode) { // Write Mode to 23K256 ssSelect; RWData(SR_WRITE_STATUS); // 0x01 RWData(mode); ssDeselect; } static inline void SR_writestream(uint16_t addr) { // Write a stream to 23K256 ssDeselect; // deselect if we are active ssSelect; RWData(0x02); // Send command RWData(addr >> 8); // Send upper address RWData(addr); // Send lower address } static inline void SR_readstream(uint16_t addr) { // Read a stream from 23K256 ssDeselect; ssSelect; RWData(0x03); // Send command RWData(addr >> 8); // Send upper address RWData(addr); // Send lower address } //----------------------------------------------------------------- // SPI Send / Receive static inline uint8_t RWData(uint8_t value) { UCB0TXBUF = value; // while (!(IFG2 & UCB0TXIFG)) {}; // wait for buffer ready while (!(UCB0IFG & UCTXIFG)) {}; // wait for buffer ready // while (!(IFG2 & UCB0RXIFG)); // USCI_B0 RX Received? while (!(UCB0IFG & UCRXIFG)); // USCI_B0 RX Received? spi_rx_data = UCB0RXBUF; // Store received data return spi_rx_data; } //------------------------------------------------------------------------------------ // UART Initialisation // UART provides PC comms on 1.2 and P1.2 - uses USCI A void uart_init_4133(void) { // Configure UART pins P1SEL0 |= BIT0 | BIT1; // set 2-UART pin as second function // Configure UART UCA0CTLW0 |= UCSWRST; UCA0CTLW0 |= UCSSEL__SMCLK; // Baud Rate calculation // 8000000/(16*9600) = 52.083 // Fractional portion = 0.083 // User's Guide Table 14-4: UCBRSx = 0x49 // UCBRFx = int ( (52.083-52)*16) = 1 UCA0BR0 = 4; // 8000000/16/9600 UCA0BR1 = 0x00; UCA0MCTLW = 0x5500 | UCOS16 | UCBRF_1; UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI } /* void uart_init(void) { P1SEL = RXD + TXD; P1SEL2 = RXD + TXD; UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 156; // 1MHz 9600 UCA0BR1 = 0; // 1MHz 9600 UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine } */ //--------------------------------------------------------------------- // UART Primitive Routines uart_putc and uart_get_c unsigned char uart_getc() { // while (!(IFG2&UCA0RXIFG)); // USCI_A0 RX buffer ready? while (!(UCA0IFG&UCRXIFG)); // USCI_A0 RX buffer ready? return UCA0RXBUF; } void uart_putc(unsigned char c) { while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = c; // TX } void uart_puts(const char *str) // Output a string { while(*str) uart_putc(*str++); } //------------------------------------------------------------------------ // Print a long unsigned int number void printlong(unsigned long num) { if (num / (unsigned long)10 != 0) printlong(num / (unsigned long)10); uart_putc((char)(num % (unsigned long)10) + '0'); return; } //--------------------------------------------------------------------------- // Print a CR-LF void crlf(void) // send a crlf { uart_putc(10); // uart_putc(13); } void print_ok() {uart_puts((char *)"OK\n\r"); } //------------------------------------------------------------------------------------ // Initialise the ADC on the '4133 void ADC_init_4133(void) { } /* //------------------------------------------------------------------------------------- // ADC Configuration void ConfigureAdc(void) { ADC10CTL1 = INCH_3 + ADC10DIV_3 ; // Channel 3, ADC10CLK/3 ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE; // Vcc & Vss as reference, Sample and hold for 64 Clock cycles, ADC on, ADC interrupt enable ADC10AE0 |= BIT3; // ADC input enable P1.3 } int ADC_Read(void) { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start ADC_value = ADC10MEM; return ADC_value; } */ //------------------------------------------------------------------------------------- // mS delay routine void delay_mS(int j) { volatile unsigned long i; while(j) { i = 42; // Delay do (i--); while (i != 0); // busy waiting (bad) j--; } } //--------------------------------------------------------------------------------- void setup(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode // Serial.begin(100000); // initialises timing functions // BCSCTL1 = CALBC1_1MHZ; // Set DCO // DCOCTL = CALDCO_1MHZ; P1DIR = BIT0 + BIT6; // P1.0 and P1.6 are the red+green LEDs P1OUT = BIT0 + BIT6; // All LEDs off uart_init_4133(); // Initialise the '4133 UART for 96000 baud spi_init_4133(); // Initialise the '4133 SPI on USCIB 8MHz clock, master mode uart_puts((char *)"MSP430 SIMPLEX\n\r"); // send opening banner message spi_check(); // Make sure SPI RAM is connected and in the correct streaming mode // P1SEL |= BIT3; // ADC input pin P1.3 ADC_init_4133(); WDTCTL = WDTPW + WDTTMSEL + WDTIS1; // enable watchdog - interval mode parray = &array[0][0]; // parray is the pointer to the first element of code buffer px_array = &block_array[0]; // px_array is pointer to first element of RAM transfered block array delay(1); time = micros(); printlong(time); // used for timing functions crlf(); LCD_print_4133(); } void loop(void) { //------------------------------------------------------------------------------- // Interpreter Loop while(1) { textRead(buf, 64); // This is the endless while loop which implements the SIMPL interpreter - just 3 simple functions textChk(buf); // check if it is a : character for beginning a colon definition textEval(buf); } // end of interpreter loop } // End of main //------------------------------------------------------------------------------- // Language Functions - Words // ------------------------------------------------------------------------------ // Read the character into the buffer void textRead (char *p, byte n) { byte i = 0; while (i < (n-1)) { char ch = uart_getc(); if (ch == '\r' || ch == '\n') break; if (ch >= ' ' && ch <= '~') { *p++ = ch; i++; } } *p = 0; } // --------------------------------------------------------------------------------------------------------- void textChk (char *buf) // Check if the text starts with a colon and if so store in user's word RAM array parray[] { if (*buf == ':') { char ch; int i =0; while ((ch = *buf++)){ if (ch == ':') { uart_putc(*buf); // get the name from the first character uart_putc(10); uart_putc(13); name = *buf ; buf++; } bufWrite((parray + (len*(name-65) +i)),*buf); i++; } x = 1; } } // --------------------------------------------------------------------------------------------------------- void textEval (char *buf) { char *loop; char *start; char ch; unsigned long k = 0; while ((ch = *buf++)) { // Is it a number? switch (ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': x = ch - '0'; while (*buf >= '0' && *buf <= '9') { x = x*10 + (*buf++ - '0'); // If a number store it in "x" } break; //------------------------------------------------------------------------------- // User Words case 'A': // Point the interpreter to the array containing the words case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': textEval(parray + (len*(ch-65))); // Evaluate and execute the User's expression fo RAM break; //--------------------------------------------------------------------------------- // (a - h hijacked for SPI RAM extensions - SIMPLEX!) case 'a': // Address (for writing to RAM) address =(x); break; case 'b': // Block - fetch a block from external memory get_block(x); break; case 'c': // Compile hex_print_2(x); break; case 'd': // HEX Dump - dump x bytes starting at address y hex_dump(y,x); print_ok(); break; /* case 'd': // Decimal Dump dump(y,x); // dump y bytes starting at address x break; */ case 'e': // Execute execute_block(x); break; case 'f': // File // fill y bytes starting at address x with test data spi_fill(y,x); print_ok(); break; case 'g': // Go run_block(); break; case 'n': // Go LCD_display_n(x); break; //-------------------------------------------------------------------------------- // Primitive and User vocabulary defined in this section // Timing & Printing Group case 'p': printlong(x); // print long integer break; case 'q': // print integer with crlf printlong(x); crlf(); break; case 't': time = micros(); printlong(time/16); // used for timing functions crlf(); break; case 'v': time = micros(); printlong(time/16); // used for timing functions crlf(); break; /* case 'd': d = x; break; */ case '_': // Print the string enclosed between underscores eg. _Hello_ while ((ch = *buf++) && ch != '_') { uart_putc(ch); } uart_putc(10); break; case 92 : // ASCII 92 forward slash \ Copy the text enclosed between \ and \ to RAM while ((ch = *buf++) && ch != 92) { uart_putc(ch); } uart_putc(10); put_block(address); break; //---------------------------------------------------------- // Arithmetic Group case '+': x = x+y; break; case '-': x = x-y; break; case '*': x = x*y; break; case '/': x = x/y; break; case '%': x = x%y; break; case 'x': x = x + 1; break; case 'y': y = y + 1; break; //-------------------------------------------------------------------- // Logical Group - provides bitwise logical function between x and y case '&': x = x&y; // Logical AND break; case '|': x = x|y; // Logical OR break; case '^': x = x^y; // Logical XOR break; case '~': x = !x; // Complement x break; case ' ': // Transfer x into second variable y k=y; // Transfer loop counter into k y= x; break; case '#': // Load x with the ASCII value of the next character i.e. 5 = 35H or 53 decimal x=*(buf-2); break; case '$': // print out a number as either a 2 digit or 4 digit Hexadecimal if(x<=255) {hex_print_2(x); break;} hex_print_4(x); break; // ---------------------------------------------------------------------- // Memory Group case '!': // store y = x; break; case '@': // Fetch x = y; break; /* case 'r': // read a byte from RAM bite = bufRead(x); // x = address x = bite; uart_putc(x); // print the character break; case 'q': // read a block of x bytes of RAM at address y for (int i=0; i<x; i++) { bite = bufRead(y+i); // read the array uart_putc(bite); // print the character to the serial port } break; case 'w': // write a byte to RAM address in y, data in x bufWrite(y,x); break; */ //-------------------------------------------------------------------- // Comparison Test and conditional Group case '<': if(x<y){x=1;} // If x<y x= 1 - can be combined with jump j else x=0; break; case '>': if(x>y){x=1;} // If x>y x= 1 - can be combined with jump j else x=0; break; case 'j': // test if x = 1 and jump next instruction if(x==1){*buf++;} break; //---------------------------------------------------------------------------------- // Print out the current word list case '?': // Print out all the RAM parray = &array[0][0]; // reset parray to the pointer to the first element for (int j = 0; j<26; j++) { uart_putc(j+65); // print the caps word name uart_putc(32); // space for (int i=0; i<len; i++) { in_byte = bufRead( parray + (j *len )+i); // read the array uart_putc(in_byte); // print the character to the serial port } crlf(); } for(int i = 0; i <11; i++) // add some spaces to make it more legible on the page { crlf(); } break; //---------------------------------------------------------------------------------------------------- // Conditional Code branch case '[': // The start of a condition test k = x; start = buf; // remember the start position of the test while ((ch = *buf++) && ch != ']') { // get the next character into ch and increment the buffer pointer *buf - evaluate the code } case ']': if (x) { // if x is positive - go around again buf = start; } break; //-------------------------------------------------------------------------- // Case Statement Selection // Select some code from a list separated by commas //5(0p,1p,2p,3p,4p,5p,6p) should select 5 and print it case '(': k = x; // copy x to use as the "phrase counter" // decrement k to see whether to interpret or not while (k) { ch = *buf++; if (ch == ',') { k--;} } break; case ',': k--; // while (k<0) // k < 0 so skip the remaining entries in the list { ch = *buf++; // skip the remaining characters if (ch == ')') {break;} } break; //----------------------------------------------------------------------------------------------------------------------------------------------- // Analogue and Digital Input and Output Group - these add heavily to total - need to be converted to MSP430 case 's': // x = ADC_Read(); // Adds 38 bytes break; /* case 'a': analogWrite(d,x); // adds 340 bytes break; case 'i': x = digitalRead(d); // adds 100 bytes break; case 'o': digitalWrite(d, x%2); // adds 18 bytes break; */ //------------------------------------------------------------------- // Delays Group case 'm': delay(x<<4); break; case 'u': delayMicroseconds(x<<4); break; //--------------------------------------------------------------------- case '{': k = x; loop = buf; while ((ch = *buf++) && ch != '}') { } case '}': if (k) { k--; buf = loop; } break; case 'k': x = k; break; // ----------------------------------------------------------------------------- // Launchpad LED group support for red and green LEDs on entry level LaunchPad case 'w': { P1OUT |= BIT0; } break; case 'r': { P1OUT &= ~BIT0; } break; case 'h': { P1OUT |= BIT6; } break; case 'l': { P1OUT &= ~BIT6; } break; // ---------------------------------------------------------------------- } } } //----------------------------------------------------------------------------- // SPI RAM Extensions to SIMPL Test routines etc //--------------------------------------------------------------------- char RAM_stream_mode() { ssDeselect; delay_1ms; uint8_t chipMode; chipMode = SR_getMode(); // check status register for sequential mode if (chipMode != 0x41) { SR_setMode(0x41); return 0; } return 1; } //--------------------------------------------------------------------------- // Check that the external RAM is present and that it is in Sequential Mode int spi_check() { ssDeselect; delay_1ms; uint8_t chipMode; // make sure there is a 23K256 chip and that // is wired properly and in sequential mode chipMode = SR_getMode(); if (chipMode != 0x41) { SR_setMode(0x41); uart_puts((char *)"SPI RAM not found\n\r"); } else { uart_puts((char *)"32K SPI RAM Connected!\n\r"); } } //-------------------------------------------------------------------------- // RAM mode // Where mode = // 0x01 Byte Mode // 0x81 Page Mode (Page = 32 bytes) // 0x41 Sequential Mode //-------------------------------------------------------------------------- char RAM_byte_mode(char mode) // Set the RAM into the correct mode { ssDeselect; uint8_t chipMode; chipMode = SR_getMode(); // check status register for byte mode if (chipMode != mode) { SR_setMode(mode); return 0; } return 1; } // ----------------------------------------------------------------------------- //spi_fill()- fill the RAM from address with "initial orders" characters // ----------------------------------------------------------------------------- void spi_fill(int address, int length ) // fill { uint16_t i; char storedValue = 0; RAM_stream_mode(); SR_writestream(address); // start writing at address for(j=0; j<6; j++) { for (i = 0; i < 32; ++i) { storedValue = int (array[j][i]); RWData(storedValue); } } } //----------------------------------------------------------------------------------------- void put_block(int address) { uint16_t i; char storedValue = 0; RAM_stream_mode(); SR_writestream(address*32); // start writing at address for (i = 0; i < 32; ++i) { storedValue = int (buf[i]); // copy key buffer to RAM block if(storedValue != 92) // omit opening \ and closing \ { RWData(storedValue); uart_putc(storedValue); } } // ----------------------------------------------------------------------------- // dump the characters from RAM to screen - putting a newline every 64 bytes // ----------------------------------------------------------------------------- void dump(int address, int length) { int i =0; crlf(); // Start with a newline! RAM_stream_mode(); SR_readstream(address); // start reading at address 0 for (i = 0; i < length ; ++i) { if(i%32 == 0) { crlf(); // put a newline every 32 chars printlong(i+ address); // print the line address followed by four spaces uart_putc(0x20); uart_putc(0x20); uart_putc(0x20); uart_putc(0x20); } RAM_byte = RWData(DUMMY_BYTE); if(RAM_byte <= 31) {RAM_byte = '.';} // Make it a full stop for unprintable characters uart_putc(RAM_byte); } } //-------------------------------------------------------------------------------------------- // Generate a familiar hex dump of the RAM area void hex_dump(int address, int length) { crlf(); // Start with a newline! int i =0; SR_readstream(address); // start reading at address 0 for (j = address >>5; j <= (address +length)>> 5 ; ++j) { for (i = 0; i < 32 ; ++i) { if(i== 0) { hex_print_4(j<<5); // print the line address as HEX followed by 2 spaces uart_putc(0x20); uart_putc(0x20); } RAM_byte = RWData(DUMMY_BYTE); // Now read and print the data as numbers // printlong(RAM_byte); hex_print_2(RAM_byte); block_array[i] = RAM_byte; // block_array is a temporary buffer to hold current RAM block uart_putc(0x20); // followed by a space } uart_putc(0x20); // Separate columns with 3 spaces uart_putc(0x20); uart_putc(0x20); for (i = 0; i < 32 ; ++i) // start reading back at address 0 so as to print the characters { RAM_byte = block_array[i]; if(RAM_byte <= 31 || RAM_byte >= 127) {RAM_byte = '.';} // Print a full stop for all unprintable characters uart_putc(RAM_byte); } crlf(); // put a newline every 32 chars } } //----------------------------------------------------------------- // Convert a char into a 2 character hex pair void hex_print_2(int dec_value) { ha = dec_value >> 4; hex_print_char(ha); ha = dec_value - (ha << 4); hex_print_char(ha); } //----------------------------------------------------------------- // Convert an int into into a 4 character hex pair // note all binary mults and divs should use shift ops for efficiency void hex_print_4(unsigned int decimal_value) { int div_value = decimal_value >> 8; hex_print_2(div_value); dec_value = decimal_value - (ha << 8); hex_print_2(dec_value); uart_putc(32); // output a space } void hex_print_char(char hex_value) // decode the A-F numbers { if (ha <=9){hex_char = '0' + ha ;} // Digits 0-9 if (ha >= 10) {hex_char = '7' + ha ;} // Letters A-F uart_putc(hex_char); } //--------------------------------------------------------------------------- // RAM Block routines void get_block(int address) { int i =0; RAM_stream_mode(); SR_readstream(address << 5); // start reading at address for (i = 0; i <32 ; ++i) { RAM_byte = RWData(DUMMY_BYTE); block_array[i] = RAM_byte; // block_array is a temporary buffer to hold current RAM block // uart_putc(RAM_byte); } // crlf(); } //--------------------------------------------------------------------------------------------- void execute_block(int address) // Load a block and execute it { get_block(address); run_block(); } //--------------------------------------------------------------------------------------------- // Point the Interpreter at the code contained in block_array and let it execute it! void run_block() { textEval(px_array); // Evaluate and execute the User's expression fo External RAM } //---------------------------------That's All Folks--------------------------------------------- void LCD_print_4133(void) { // Configure LCD pins SYSCFG2 |= LCDPCTL; // R13/R23/R33/LCDCAP0/LCDCAP1 pins selected LCDPCTL0 = 0xFFFF; LCDPCTL1 = 0x07FF; LCDPCTL2 = 0x00F0; // L0~L26 & L36~L39 pins selected LCDCTL0 = LCDSSEL_0 | LCDDIV_7; // flcd ref freq is xtclk // LCD Operation - Mode 3, internal 3.08v, charge pump 256Hz LCDVCTL = LCDCPEN | LCDREFEN | VLCD_6 | (LCDCPFSEL0 | LCDCPFSEL1 | LCDCPFSEL2 | LCDCPFSEL3); LCDMEMCTL |= LCDCLRM; // Clear LCD memory LCDCSSEL0 = 0x000F; // Configure COMs and SEGs LCDCSSEL1 = 0x0000; // L0, L1, L2, L3: COM pins LCDCSSEL2 = 0x0000; LCDM0 = 0x21; // L0 = COM0, L1 = COM1 LCDM1 = 0x84; // L2 = COM2, L3 = COM3 // Display "123456" LCDMEM[pos1] = digit[1]; LCDMEM[pos2] = digit[2]; LCDMEM[pos3] = digit[3]; LCDMEM[pos4] = digit[4]; LCDMEM[pos5] = digit[5]; LCDMEM[pos6] = digit[6]; LCDCTL0 |= LCD4MUX | LCDON; // Turn on LCD, 4-mux selected PMMCTL0_H = PMMPW_H; // Open PMM Registers for write PMMCTL0_L |= PMMREGOFF_L; // and set PMMREGOFF // __bis_SR_register(LPM3_bits | GIE); // Enter LPM3.5 // __no_operation(); // For debugger } void LCD_display_n(int number) { LCDMEMCTL |= LCDCLRM; // Clear LCD memory LCDCSSEL0 = 0x000F; // Configure COMs and SEGs LCDCSSEL1 = 0x0000; // L0, L1, L2, L3: COM pins LCDCSSEL2 = 0x0000; LCDM0 = 0x21; // L0 = COM0, L1 = COM1 LCDM1 = 0x84; // L2 = COM2, L3 = COM3 // Display "123456" int n = number / 100000; LCDMEM[pos1] = digit[n]; n = number - (100000*n); n = n/10000; LCDMEM[pos2] = digit[n]; n = number - (10000*n); n = n/1000; LCDMEM[pos3] = digit[n]; n = number - (1000*n); n = n/100; LCDMEM[pos4] = digit[n]; n = number - (100*n); n = n/10; LCDMEM[pos5] = digit[n]; n = number - (10*n); LCDMEM[pos6] = digit[n]; LCDCTL0 |= LCD4MUX | LCDON; // Turn on LCD, 4-mux selected }
  12. Like
    tripwire reacted to monsonite in SIMPL - A Tiny Language for MSP430   
    Hi All
    Back in May 2013, I came across a piece of development work by Ward Cunningham (wiki inventor) for a tiny interpreted language "Txtzyme" that ran on Arduino - or virtually any other micro that was supported by a C compiler.
    (The name Txtzyme comes from text and enzyme -  an enzyme being a biological catalyst - or a substance that causes (chemical) change to occur faster).
    I was intrigued how under 100 lines of C code formed such a useful and extendable language - that I quickly had it running on an Arduino, and was making my own modifications and improvements.  I have since built on Ward's work and called my project SIMPL - Serial Interpreted Microcontroller Language.
    (Link to Ward's original work is here  https://github.com/WardCunningham/Txtzyme )
    Ward had created a "nano interpreter" in just a few lines of C code, which formed the heart of an interactive language for controlling hardware.
    Through just a dozen commands it would allow port manipulation,  flashing LEDs,  musical tone generation, PWM, printing to screen and sensing analogue signals. The language communicated through a uart port to the PC.
    Originally Txtzyme offered just these commands - see Ward Cunningham's Read Me:

    a-f      Select an I/O port
    h        help - a summary of commands
    i         input
    k        a loop counter - which decrements each time around the loop  see {}
    m       millisecond delay
    o       output
    p       print the value of variable x followed by carriage return/line feed
    s       sample an ADC channel
    u       microsecond delay
    x       a 16 bit integer variable
    {}     code between these braces is repeated as a loop
    _ _    characters between the underscores are printed to the terminal
    Txtzyme was small, entensible and portable - it will run on almost any microcontroller.  The Txtzyme scripts were very small, human readable and easy to send from one device to another.
    One early application was for the Arduino to be used as an I/O controller board attached to a Raspberry Pi.  The Pi would send a simple command via it's uart and the Arduino would perform an I/O function, sequence or whatever.
    Some months later, I decided to try Txtzyme with the MSP430, as I had got a LaunchPad and Energia had just appeared on my radar. 
    So I took the original Txtzyme Arduino  sketch, loaded into Energia - and behold it worked first time.  Txtzyme was a universal "lingua franca" that could be used on any micro.
    If you want to try  arecent version of SIMPL that runs on a LaunchPad MSP430G2553 - here is the Github Gist
    Since then I have ported it to  AVR Cortex M3, M4,  and several soft-core processors running on FPGAs.
    Currently my aim is to reduce the SIMPL Kernel to approximately 2kbytes - so that it can become a "Smart Bootloader"  - residing on the microcontroller in the bootloader area, and being immediately available as an interactive toolkit for exercising hardware and performing small applications.
    I have written extensively about it in my blog  - starting here  from May 2013
    I have also just this week started a wiki - so that all the new information can reside in 1 place.
    Please get in touch if you would like to know more about SIMPL and my project aims.  
  13. Like
    tripwire reacted to spirilis in Parsing "strings" in C - Attempting to parse MQTT payload   
    Also for kicks, I ran the first code (test.c) with some extra quirks to test its limits:
    char text[] = "cmd=load&&&&&&&&&&&&&color=red&bg=blueα=0.56&&blah=&&&&=wtf&&&&";
    Here's the output:
    ebrundic@spock:~/inst$ ./test key=[cmd], value=[load] key=[color], value=[red] key=[bg], value=[blue] key=[alpha], value=[0.56] key=[blah], value=[] key=[wtf], value=[wtf] The only output that seems odd is the "=wtf" case, since the code took the value and pointed both key and value pointers to the value.  A state variable (called no_key here) could protect against this:
    #include <stdio.h> #include <stdint.h> #include <sys/types.h> #include <string.h> void run_callback(const char *, const char *); int main(int argc, char *argv[]) { size_t i; char text[] = "cmd=load&&&&&&&&&&&&&color=red&bg=blueα=0.56&&blah=&&&&=wtf&&&&"; size_t tlen = strlen(text); char *key=NULL, *value=NULL; int no_key = 0; for (i=0; i < tlen; i++) { if (text[i] == '&') { // end of key/value pair text[i] = '\0'; if (key != NULL) { run_callback(key, value); } key = NULL; value = NULL; no_key = 0; continue; } if (text[i] == '=') { // end of key, start of value no_key = 1; text[i] = '\0'; value = &text[i+1]; continue; } if (!no_key && key == NULL) { key = &text[i]; } // otherwise do nothing, keep incrementing i } // end of string, we might have a loaded key/value pair to process at the very end if (key != NULL) { run_callback(key, value); } return(0); } void run_callback(const char *key, const char *value) { if (key == NULL || value == NULL) { printf("key=ptr[%p], value=ptr[%p]\n", key, value); } else { printf("key=[%s], value=[%s]\n", key, value); } } which produces:
    key=[cmd], value=[load] key=[color], value=[red] key=[bg], value=[blue] key=[alpha], value=[0.56] key=[blah], value=[]
  14. Like
    tripwire reacted to bluehash in Forum reset to March 5th, 2016   
    Hello All,
    If you have been following the upgrade, there was an issue.
    Unfortunately I was unable to get the code to format correctly. I'm still working it out with support.
    Note that members registered between the 5th and 7th, you will have to register again. There was one post made, but I have that person's email, so I'll get in tough with him.
    Hopefully the downgrade went well. If you see any issues, please raise it up immediately.
  15. Like
    tripwire reacted to Rickta59 in Have you experienced a chilling effect?   
    For msp430 topics, there are users in #43oh channel on freenode.net. 
    http://webchat.freenode.net/?channels=43oh&nick=guest_from_post ... replace the nick with a better one if you like
  16. Like
    tripwire reacted to agaelema in Products using MSP430   
    Teardown Tuesday: Kwikset SmartCode Lock

  17. Like
    tripwire reacted to Fred in Stupidest Thing you had to Troubleshoot?   
    I've managed a few. Swapping VCC and VSS on my first etched PCB was a good one. I'm glad I'm not the only one who's done that.
    I also noticed that a TS430RGC64USB target board that I had supported the F5510 that I was coding for. Great! So I stuck it in and wondered why it didn't work. It turns out that a LQFP48 will fit in a QFN64 socket. It might not fit that well or work, but it goes in.
    Amazingly neither of these (and probably worse that I've forgotten) damaged the MSP430.
  18. Like
    tripwire reacted to cde in Free shipping at Arrow, including Launchpads and dev kits   
    Applies to FedEx Ground, UPS Ground, USPS First Class Mail and FedEx International Economy only.
    I wonder what the Customs fee would be though. Some info says Fedex Int Economy has no brokerage fee.
  19. Like
    tripwire reacted to bluehash in Free shipping at Arrow, including Launchpads and dev kits   
    Good to use if you want to escape the $7 TI Store shipping.
    No code needed.
  20. Like
    tripwire reacted to L.R.A in Great deals in the TI Store Celebrating Engineers Week!   
    This aren't that great anymore IMO. Just because for me it's 30$ shipping. I need to get a ton of things for it to be worth it.

    3 MSP432 are cheaper to get locally for the normal price than getting from Estore with that discount, especially due to customs.

    Lucky US ppl
  21. Like
    tripwire reacted to USWaterRockets in Great deals in the TI Store Celebrating Engineers Week!   
    Some good deals here on a number of development tools!
    12 great deals there, including the return of the popular $4.32 MSP432 Launchpad!
  22. Like
    tripwire reacted to Clavier in power consumption for sensors/ parts in sleep mode   
    If those sensors/parts use too much power when idle, you need to switch them off somehow.
    If they don't have a power-down command/signal, you have to switch off their VCC. This can be done either with a transistor (a logic-level MOSFET would need slightly less power than a BJT), or directly with a GPIO if the sensor does not need much power.
    Please note that some chips do not allow high voltages on their I/O pins when VCC is zero; those might need protection, too.
  23. Like
    tripwire reacted to sq7bti in Newtonian/Dobsonian telescope controller   

    A summary of changes:
    instead of unipolar motor drivers, now I used a bipolar drivers very popular in RepRap projects, here A4988 (or DRV8825) 28byj-48 modified for bipolar cheap HC-05 for bluetooth SPP GPS module U-blox NEO-6m added RTC DS1307 to provide date/time reference even in the first seconds after power-on and 56 of NVRAM bytes added (optional) humidity and temperature sensor DSTH01 added a I2C socket to connect external temperature sensors to provide information about motors temperatures added PCF8574 for microstepping configuration of A4988 drivers added buzzer for audible indication added output for 12Vdc fan of main mirror - PWM controlled Nokia 5110 display replaced with a red back-light
    As the software is concerned, there were several improvements as well. The most important is that the motors are now driven by an interrupt driven AccelStepper

    With kind regards,
  24. Like
    tripwire reacted to sq7bti in Newtonian/Dobsonian telescope controller   
    When powered on, the mount moves to the first alignment star. Then, a user provides the correction vector: star just needs to be positioned in the middle of view in eyepiece. First star roughly corrects the misalignment in telescope orientation w.r.t. the north. Second star helps to correct also the leveling error. Third star would improve alignment even further. I did not (yet) implement any periodic error correction. The whole alignment procedure takes couple of minutes, and requires a user to center stars in an eyepiece with an attached joystick, and confirm with fire button. GPS resolves the time/date and location issue during start-up in unknown location.
    with kind regards,
  25. Like
    tripwire reacted to sq7bti in Newtonian/Dobsonian telescope controller   
    Hello everyone,
    There is a couple of similar projects available on the internet. Some of them base on Arduino and PIC performs very basic mount control without math intensive computation implemented in embedded controller. I decided to build my own with the following goals:
    ease of use by an inexperienced amateur astronomer (full automatic operation) precision and resolution of position  last but not least: the price Final, or better say at the moment, design comprises of the following components:
    Stellaris LM4F launchpad central control unit, two ULN2003 unipolar stepper motor driver chips, two 28byj-48 stepper motors one moving in azimuth, and in elevation via gear train, communication module: Bluetooth serial module. It allows sending a coordinate set-point and provides position feedback to Stellarium, GPS module providing position and precise time reference - PPS gives 1us accuracy, Nokia 5110 display unit and joystick for standalone operation, now obsolete mouse (PS/2) modified to provide independent (incremental) position information Resolution that was reached is a single step of approx. 5". Given the size of Jupiter to range from 30" to 50", this positioning resolution makes the view comfortably stable in standard 60° FOV eyepiece at reasonably high magnification, without the need to adjust AZ/ALT continuously.
    During the development I made use of several opensource and projects available online, namely:
    AccelStepper for stepper control, TinyGPS++ for NMEA decoding, Arduino telescope controller was my inspiration and reference for Taki's matrix method for coordinates transformation, of course Energia as my IDE Upon power-up the mount is performing:
    homing acquisition of current location (longitude/latitude) and time via NMEA stream moves to 3 brightest (most convenient) stars in succession to perform 3 star alignment procedure - they are selected from the list of over 500 stars in built-in catalog (the  brightest are used for the alignment, tough), once aligned the mount is in tracking mode: it tracks the view to counter the apparent movement of objects in the sky, waiting, either for the user to move to particular object - selected from the library of stars and Messier objects, or awaits connection via Bluetooth from a PC running Stellarium with a plugin and slews to selected object. search for the object that should be visible in the eyepiece and display important information on LCD - I compiled in 500 brightest stars from HYGXYZ and full Messier catalog.  I have very little experience as amateur astronomer so far, so some of the objectives might have been not very obvious for me in the beginning. This project was also a good way to make use of my free time and gain experience in embedded system design.
    With kind regards,
  • Create New...