Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 27

Thread: Teensyduino 1.40 Beta #2

  1. #1
    Administrator Paul's Avatar
    Join Date
    Oct 2012
    Posts
    266

    Teensyduino 1.40 Beta #2

    Here is a second beta test for Teensyduino 1.40.

    Linux 32 bit:
    https://www.pjrc.com/teensy/td_140-b...nstall.linux32

    Linux 64 bit:
    https://www.pjrc.com/teensy/td_140-b...nstall.linux64

    Linux ARM:
    https://www.pjrc.com/teensy/td_140-b...stall.linuxarm

    Mac OS-X:
    https://www.pjrc.com/teensy/td_140-b...inoInstall.dmg

    Windows:
    https://www.pjrc.com/teensy/td_140-b...inoInstall.exe


    Changes since Teensyduino 1.40-beta1

    Support for Arduino 1.8.5
    Fix delay when uploading on Linux

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    If you downloaded Arduino before 7 AM (pacific time) Oct 2, delete the files and download again. Files built with the wrong i18n translation files were briefly on Arduino's download page.

    The correct Arduino 1.8.5 files have these MD5s:

    Code:
    195dfda00f9460e5a7f24f13dfbebe23  arduino-1.8.5-linux32.tar.xz
    a95fa15b88b8dc4ddb79ac28665f763b  arduino-1.8.5-linux64.tar.xz
    7fe669998592b795423f09709f58d23e  arduino-1.8.5-linuxarm.tar.xz
    4a0dd99a006ea91376793a763f2ebd9a  arduino-1.8.5-macosx.zip
    cb46bcea9fb8efb3721174dcea637d8f  arduino-1.8.5-windows.zip

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    If anyone has any fixes or low-risk features I should merge, please speak up. At the moment I have Kurt's recent USB Host work on my radar for 1.40-beta3.

    Over the last couple days I've been working mostly to catch up to the last couple weeks of forum messages I've missed. I've also been doing more testing. Turns out on Linux and Mac, many of the errors which are supposed to show up in Arduino's console are missing. It seems to be due to a bug added when I was forced to change how platform.txt runs the post compile utility, which then runs the reboot utility. I'm a little embarrassed I didn't notice this earlier, and so far nobody's complained.... but it's definitely a bug! I'm fixing it now and will have 1.40-beta3 out soon.

    Also, while answering questions yesterday, I had a tiny epiphany. The Teensy Loader window shows "Press Button on Teensy to manually enter Program Mode", even during the time when Arduino is running teensy_reboot. I'm going to change this so the Teensy Loader window shows this message when teensy_reboot is trying to find and reboot.

    Name:  sc.png
Views: 639
Size:  39.2 KB

    It's a subtle change. But if the reboot isn't working or is just going slow (eg, Windows New Hardware Wizard blocking), hopefully this minor change can make things less confusing.

    There are probably many other little UI tweaks that could help. Honestly, I'm just too close to the tech details to see them. I also usually leave Teensy Loader alone "ain't broke, don't fix" for most releases. But maybe there are other small UI improvements that could help people understand what's going on? (redoing the Tools > Ports menu in Arduino is on my list, but that's a big project)

  4. #4
    Senior Member jimmayhugh's Avatar
    Join Date
    Nov 2012
    Posts
    168
    Basics work fine 0n Debian 8.9 and 9.1

  5. #5
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    879
    Can you update Snooze please.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    Quote Originally Posted by duff View Post
    Can you update Snooze please.
    Done. It'll be in 1.40-beta3. Plan is to wrap that up tomorrow, and then a final 1.40 early next week.

  7. #7
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    42
    Hi Paul,

    One detail about the Teensy Loader that's a very minor nuisance (maybe only to me) is the way it steals focus when I click the upload button on the Arduino IDE. I usually forget to re-click on the IDE before I try to cntrl-z whatever failed experiment I just tried--then have a WTF moment.

    That said, let me add that I think you do a brilliant job with Teensy and the other PJRC products.

    thanks,
    Michael

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    Quote Originally Posted by Michael Ward View Post
    the way it steals focus when I click the upload button on the Arduino IDE.
    Which platform is this?

    I just tested on Windows 10 and Ubuntu 14.04. Can't seem to reproduce it.

    Maybe I'm not clicking quite the same way? Here's what I tried. 1. Type some extra text "int a=0;". 2: Move the mouse to the upload button. 3: Click the button, and take my hand off the mouse. 4: wait for upload to complete. 5: (without touching the mouse again, cursor still over the upload button) Type Ctrl-Z.

    Right now is the perfect time to address this. I don't usually do much with Teensy Loader, but this recent change on the Linux side and improving the USB detection for (someday) improving the Ports menu means I have all the code open. My goal has always been to make Teensy Loader not annoying (except I'm going to add a nag dialog for some counterfeit boards). If it's grabbing focus, I'd really like to fix and fix the problem.

  9. #9
    Member tcottle's Avatar
    Join Date
    Dec 2014
    Location
    Longmont, CO
    Posts
    29
    Hi Paul

    A reset button would be handy - sometime my power supply is further than an arms length away

  10. #10
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    42
    I'm running on Linux Mint. I seem to recall that this used to happen on Win too, but I can't swear to it. When I get home (at work now) I'll check my Macbook.
    Anyhow, click the upload button (or type ctrl-u) and the Teensy Loader pops from background to foreground while the upload happens then stays there. Any typing now disappears into Timbulia unless I click on the IDE to bring it back into the foreground. If the Teensy Loader is minimized, it pops onto the screen in the foreground over the IDE.
    As I said--minor.

    thanks,
    Michael

    Edit:
    That's Mint 18.1. Far as I understand, it should behave the same as Ubuntu.
    And the Macbook has the same Teensy Loader behavior. Using Arduino 1.8.4 and Teensy Loader 1.38
    --Michael
    Last edited by Michael Ward; 10-06-2017 at 11:31 PM.

  11. #11
    Moderator Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,347
    Quote Originally Posted by tcottle View Post
    Hi Paul

    A reset button would be handy
    Yes, indeed.

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    By "reset button", do you mean a way to put Teensy into programming mode without automatically uploading your code?

    Or are you asking for a button that will cause Teensy to try to do something like a hardware reset, so it runs your program again from the beginning with all the hardware (even the USB) in a "clean slate" condition?

    Or a simulated reset (like Arduino Uno), as was done on Teensy 2.0 when you open the serial monitor. In that scenario, the USB is kept active and code tries to do something similar to resetting as much hardware as it can, then it jumps back to the beginning of your program. So your code mostly resets, but the USB doesn't disconnect and reconnect (where you lose your connection to the USB serial device - and trigger the horrible USBSER bug on Windows XP/7/8).

    Or something else?

  13. #13
    Moderator Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,347
    A function that calls the software-reset (not programming-mode) - like TYQT it has. This button is really handy.

  14. #14
    Moderator MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    2,539
    While at times I wish for a reset button (in addition to the programming button), I really would prefer a simple switch to disable power (at least between VIN and VUSB, obviously power supplied to VIN directly is harder). I do generally solder a wire to the reset pad on the 3.2, and of course 3.6/3.5 bring it out as a regular pin to provide the reset.

    Typically for the reset action, I can just disable power, and restart it.

  15. #15
    Moderator Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,347
    @Michael: We were speaking about a button in the teensy-loader - pure software.
    For Hardware: I've "hacked" a USB-Cable and added a jumper to the "+" line. I can use it to measure the milliAmps - or - add a switch.
    @Paul: Such a cable would be a useful addon, too

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    At this moment, I'm really focused on trying to streamline the UI that's already in place, fix any bugs or annoyances.

    I know it's much more fun to talk of new features. I also know it can be kind of disappointing when they don't happen, or at least not on any reasonable time frame.

    It's ok to chat here, but please understand the input I'm looking for at this moment is the minor little bugs, and the usability problems that I would normally never notice because I know too much about how it's supposed to work.

  17. #17
    Member tcottle's Avatar
    Join Date
    Dec 2014
    Location
    Longmont, CO
    Posts
    29
    Quote Originally Posted by PaulStoffregen View Post
    Or are you asking for a button that will cause Teensy to try to do something like a hardware reset, so it runs your program again from the beginning with all the hardware (even the USB) in a "clean slate" condition?
    Or something else?
    A power on reset function. For testing now I just cycle the power supply (I have the USB supply isolated). It would be handy since Teensy loader is always available after the first upload.

    If it doesn't make the cut that is fine as well ;-)

  18. #18
    Paul: I did a Pull request for XPT2046_Touchscreen. Doing DMA to the ILI9341 on shared SPI lines can make use of the TIRQ pin when a touch can be detected without pinging the SPI. I added XPT2046_Touchscreen::tirqTouched that works like touched() - that instead returns the state of the IRQ isrWake flag used to track the touch instead of actually calling out an UPDATE when detected. When TRUE this would allow a clean halt to DMA to read touch only when detected.

    https://forum.pjrc.com/threads/38752...l=1#post155722

    I've tested it to compile - AFAIK it is a trivial and safe edit. Would be nice if Donziboy2 tested it to work if you would consider it of use.

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,885
    Ok, I *finally* managed to reproduce this problem!

    Click image for larger version. 

Name:	readerr.png 
Views:	32 
Size:	9.7 KB 
ID:	11711

    It's looking like a race condition between Arduino->teensy_post_compile->teensy_reboot and Teensy Loader.

    I'm attempting a fix now. Hopefully 1.40-beta3 will *finally* fix this long standing bug!

  20. #20
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    42

    Problem with SPI.end()

    HI,

    The attached sketch files run light patterns on strings of leds (called "footlights" because they're 12 inches long) driven by shift registers. Most of these routines use SPI, but there is one that toggles the pins manually and needs SPI temporarily disabled. This works fine on an Uno and has worked fine on a Teensy 3.2 and a T3.6 with Teensyduino 1.36. However, with 1.37, and now with 1.4, the non-SPI routine fails.

    I'm hoping this is just some new detail of usage that I don't know about.

    The attached code is a simplified version of my sketch including just 2 routines, an SPI and a non-SPI routine. Description of the attached files:
    - demo_simple1.ino -- the main sketch file; in this implementation it alternates between running the 2 routines
    - ChainGang_1color_lite.h -- a class for easily addressing the outputs on chained shift registers, usage similar to digitalWrite: object_name.setChain(output_number, state)
    - chasers.ino -- the SPI-using routine that runs fine on all versions
    - cascade.ino -- the non-SPI routine that fails with newer T-duino versions

    demo_simple1.ino
    Code:
     /* ***********************************************************************************************************
     * Footlights/simple_demo.ino
     * Output to chained 74HC595s driving "footlights" of 120 leds each. 
     * M Ward 12/04/2014, latest edit 8/31/17
     *************************************************************************************************************/
    
    #define QUANT_FEET    2               // Number of 120-led, 15-shift register footlights
    #define QUANT_REG    QUANT_FEET * 15  // Number of chained 8-bit shift registers
    #define MAX_CHASERS  QUANT_FEET * 4   // Arbitrary maximum number, enough for all routines
    #define LATCH         9               // Shift register control
    #define DATA         11               // DATA and CLOCK defined for non-SPI routine(s)
    #define CLOCK        13
    #define BAIL_BTN      5
    #define MIN_RUN   15000               // Routine run time randomization limits
    #define MAX_RUN   30000
    
    //#include "digitalWriteFast.h"         // Uncomment for AVR
    #include <SPI.h>
    #include <Bounce.h>
    #include "ChainGang_1color_lite.h"
    Bounce bail(BAIL_BTN, 10); 
    ChainGang chaser[MAX_CHASERS];
    uint32_t runStart;
    uint32_t runTime;
    bool routineSet = false;
    bool reStart = false;
    
    //=========================================== setup =========================================================+
    void setup() {
      randomSeed(analogRead(A0));
      pinMode(DATA, OUTPUT);
      pinMode(CLOCK, OUTPUT);
      pinMode(LATCH, OUTPUT);     // Use pinModeFast for AVR
      pinMode(BAIL_BTN, INPUT_PULLUP);
      SPI.begin();
      SPI.beginTransaction(SPISettings(24000000, MSBFIRST, SPI_MODE0));
      Serial.begin(1000000);
      Serial.println(F("Sketch:   Footlights/demo_simple\n"));
    }
    
    //=========================================== loop ==========================================================+
    void loop() {
      const uint8_t quantRoutines = 2;
      static uint8_t routine;
      buttonCheck();
      if (!routineSet) routine = chooseRoutine(quantRoutines);
      switch(routine) {
        case 1:
          cascade();
          break;
        case 0:
          chasers(250, 15000);      // (min_stepTime, max_stepTime) micros
        break;
      }
    }
    
    //------------------------------------------- chooseRoutine -------------------------------------------------+
    uint8_t chooseRoutine(uint8_t quantRoutines) {
      static uint8_t lastRoutine = random(quantRoutines);
      uint8_t choice;
      choice = random(quantRoutines);
      if (choice == lastRoutine) chooseRoutine(quantRoutines);
      else {
        lastRoutine = choice;
        return choice;
      }
    }
    
    //------------------------------------------- buttonCheck ---------------------------------------------------+
    void buttonCheck() {
      bail.update();
      if (bail.fallingEdge()) {     // Check whether to abort routine
        reStart = true;
        Serial.println(F(">>>>>>>>> RESTARTED <<<<<<<<<\n"));
      }
    }
    ChainGang_1color_lite.h
    Code:
     /* ***********************************************************************************************************
     * The ChainGang class is for easily controlling the outputs in an arbitrary number of chained shift
     * registers, eg, 74HC595s. Usage similar to digitalWrite:
     *  - object_name.setChain(output_number, state)
     *  - Be sure to define QUANT_REG before including ChainGang. It assumes 8-bit devices or equivalent--
     *    eg, define QUANT_REG = 4 for a 32-bit '6818
     * M Ward 12/04/2014, latest edit 9/12/17
     *************************************************************************************************************/
    
    #ifndef CHAINGANG_1COLOR_H
    #define CHAINGANG_1COLOR_H
    
    const uint16_t QUANT_OUT = QUANT_REG * 8;
    const uint16_t LAST_OUT = (QUANT_REG * 8) - 1;   // Last output in chain, zero-relative
    
    //------------------------------------------- ChainGang lite ------------------------------------------------+
    class ChainGang {
    private:
      static uint8_t link[QUANT_REG];    // Array of byte-sized elements for output to byte-sized shift registers
    public:
      uint16_t location;    // Outputs by number--0 through LAST_OUT
      uint16_t outFirst;    // outFirst/Last can be used to divide chains into zones
      uint16_t outLast;
      uint8_t  dir;         // Right/Left
      uint32_t stepTime;
      uint32_t stepStart;
      ChainGang() {
        outFirst = 0;
        outLast = LAST_OUT;
      }
      //------------------- xferLinks -----------------------+
      static void xferLinks() {          // Transfer array contents to shift registers
        digitalWriteFast(LATCH, LOW);
        for (int8_t n = QUANT_REG - 1; n >= 0; n--) SPI.transfer(link[n]);
    //    SPI.transfer(link, QUANT_REG);
        digitalWriteFast(LATCH, HIGH);
      }
      //------------------- setChain ------------------------+
      static void setChain(uint16_t outputNum, uint8_t state) {
        uint8_t linkNumber = outputNum >> 3;                     // Calculate which link holds output--ie, / 8  or sizeof(link[0])
        uint8_t linkPosition = outputNum - (linkNumber << 3);    // Position of output within link
        bitWrite(link[linkNumber], linkPosition, state);         // Write to link
        ChainGang::xferLinks();
      }
      //------------------- clearChain ----------------------+
      static void clearChain() {
        for (uint8_t n = 0; n < QUANT_REG; n++) link[n] = 0;
        ChainGang::xferLinks();
      }
    };
    uint8_t ChainGang::link[QUANT_REG];
    
    #endif
    chasers.ino

    Code:
    //------------------------------------------- chasers -------------------------------------------------------+
    void chasers(uint32_t intervalMin, uint32_t intervalMax) {
      static uint8_t quantChasers = random(2, MAX_CHASERS);
      if (!routineSet) {
        runTime = random(MIN_RUN, MAX_RUN);
        runStart = millis();
        quantChasers = random(2, MAX_CHASERS);
        if (quantChasers < 3 || quantChasers > 8) quantChasers = random(2, MAX_CHASERS); // Weight number toward midrange
        uint8_t startEnd = random(2);                                                    // Decide which side to start from
        for (uint8_t n = 0; n < quantChasers; n++) {
          !startEnd ? chaser[n].location = chaser[n].outFirst : chaser[n].location = chaser[n].outLast;
          chaser[n].stepTime = random(intervalMin, intervalMax);                         // Randomize each chaser's interval
        }
        routineSet = true;
        Serial.println(F("Routine:  POLYRHYTHM"));
        Serial.print(F("          runTime = "));
        Serial.print(runTime / 1000);
        Serial.println(F(" seconds"));
        for (uint8_t n = 0; n < quantChasers; n++) {
          Serial.print(F("          chaser["));
          Serial.print(n);
          Serial.print(F("]: "));
          Serial.print(F("stepTime (us) = "));
          Serial.println(chaser[n].stepTime);
        }
        Serial.println();
      }
      //------------------- core routine ------------------+
      if (millis() - runStart < runTime) {
        for (uint8_t n = 0; n < quantChasers; n++) {                      // For every chaser...
          if (micros() - chaser[n].stepStart >= chaser[n].stepTime) {     // If it's stepTime...
            chaser[n].stepStart = micros();
            chaser[n].setChain(chaser[n].location, LOW);                          // Current position off
            if (chaser[n].location == chaser[n].outLast) chaser[n].dir = 1;       // Check whether to change direction
            else if (chaser[n].location == chaser[n].outFirst) chaser[n].dir = 0;
            chaser[n].dir == 0 ? chaser[n].location++ : chaser[n].location--;     // Increment/decrement position
            chaser[n].setChain(chaser[n].location, HIGH);                         // New position on
          }
        }
      }
      else routineSet = false;
      if (reStart) {          // Abort routine?
        routineSet = false;
        reStart = false;
        ChainGang::clearChain();
        return;
      }
    }
    cascade.ino
    Code:
    //------------------------------------------- cascade -------------------------------------------------------+
    void cascade() {
      static bool reWind;
      static uint32_t stepTime;
      if (!routineSet) {
        stepTime = random(3, 11);
        !random(2) ? reWind = false : reWind = true;
        runStart = millis();
        runTime = random(1250, 2600);
        Serial.println(F("Routine:  CASCADE"));
        Serial.print(F("          stepTime (ms) = "));
        Serial.println(stepTime);
        Serial.print(F("          reWind = "));
        reWind ? Serial.println(F("true")) : Serial.println(F("false"));
        Serial.println();
        SPI.end();                  // Release SPI pin control
        routineSet = true;
      }
      if (millis() - runStart < runTime) {
        for (int16_t location = LAST_OUT; location >= 0; location--) bitbang(location, stepTime);
        if (reWind) for (int16_t location = 0; location <= LAST_OUT; location++) bitbang(location, stepTime);
      }
      else {
        SPI.begin();                // Restore SPI
        routineSet = false;
        reStart = false;            // Note: this routine blocks; reStart will not interrupt it
        ChainGang::clearChain();
      }
    }
    
    //------------------- bitbang -----------------------+
    void bitbang(int16_t location, uint32_t stepTime) {
      digitalWriteFast(LATCH, LOW);
      digitalWrite(DATA, HIGH);
      for (int n = 0; n < location; n++) {
        digitalWrite(CLOCK, HIGH);
        digitalWrite(DATA, LOW);
        digitalWrite(CLOCK, LOW);
      }
      digitalWriteFast(LATCH, HIGH);
      delay(stepTime);
    }
    Thanks for any help,
    Michael

  21. #21
    Moderator MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    2,539
    Quote Originally Posted by Michael Ward View Post
    HI,

    The attached sketch files run light patterns on strings of leds (called "footlights" because they're 12 inches long) driven by shift registers. Most of these routines use SPI, but there is one that toggles the pins manually and needs SPI temporarily disabled. This works fine on an Uno and has worked fine on a Teensy 3.2 and a T3.6 with Teensyduino 1.36. However, with 1.37, and now with 1.4, the non-SPI routine fails.

    I'm hoping this is just some new detail of usage that I don't know about.
    I presume the issue is SPI transactions.


    I had a similar issue in wanting to use the prop shield's level shifters on pin 11/13, and either accessing the prop shield's flash memory or using ST7735 displays. Look towards the bottom of the thread for the solution from KurtE:


    The idea is you need to wait for the DMA sequences to end (which I already was doing in the program), and then you reissue pinMode before you want to use 11/13 with digitalWrite's, and then you reset 11 (and I presume 13) into SPI mode after you are done.

    Though you might also want to investigate eliminating bitbang, and switch to use SPI commands.

  22. #22
    Moderator KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,130
    I think the difference is that earlier versions of SPI when you called .end() configured the associated IO pins as digital pins (I believe OUTPUT), whereas the current stuff sets the IO pins to the default state of disabled.

    The simplest fix would be to have your code configure the IO pins to the state you want right after the call to SPI.end();

  23. #23
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    42
    You guys are great.
    As I hoped, a simple usage issue. "cascade.ino" revised as shown below and works fine now. Everything else is unchanged except for removing the DATA and CLOCK pinModes from setup().

    Code:
    //------------------------------------------- cascade -------------------------------------------------------+
    void cascade() {
      static bool reWind;
      static uint32_t stepTime;
      if (!routineSet) {
        stepTime = random(3, 11);
        !random(2) ? reWind = false : reWind = true;
        runStart = millis();
        runTime = random(1250, 2600);
        Serial.println(F("Routine:  CASCADE"));
        Serial.print(F("          stepTime (ms) = "));
        Serial.println(stepTime);
        Serial.print(F("          reWind = "));
        reWind ? Serial.println(F("true")) : Serial.println(F("false"));
        Serial.println();
        SPI.end();                  // Release SPI pin control
        SPI.endTransaction();                   // <<<<<<<<<<<<< new line
        pinMode(DATA, OUTPUT);            // <<<<<<<<<<<<< new line
        pinMode(CLOCK, OUTPUT);         // <<<<<<<<<<<<< new line
        routineSet = true;
      }
      if (millis() - runStart < runTime) {
        for (int16_t location = LAST_OUT; location >= 0; location--) bitbang(location, stepTime);
        if (reWind) for (int16_t location = 0; location <= LAST_OUT; location++) bitbang(location, stepTime);
      }
      else {
        SPI.begin();                // Restore SPI
        SPI.beginTransaction(SPISettings(24000000, MSBFIRST, SPI_MODE0));        // <<<<<<<<<<<<< new line
        routineSet = false;
        reStart = false;            // Note: this routine blocks; reStart will not interrupt it
        ChainGang::clearChain();
      }
    }
    
    //------------------- bitbang -----------------------+
    void bitbang(int16_t location, uint32_t stepTime) {
      digitalWriteFast(LATCH, LOW);
      digitalWrite(DATA, HIGH);
      for (int n = 0; n < location; n++) {
        digitalWrite(CLOCK, HIGH);
        digitalWrite(DATA, LOW);
        digitalWrite(CLOCK, LOW);
      }
      digitalWriteFast(LATCH, HIGH);
      delay(stepTime);
    }
    Reworking cascade to use SPI would be the ideal solution, but the twisty logic of those loops has resisted easy analysis. There are so many unfinished projects on my desk right now that I'm inclined to chalk this one up in the "win" column and move on (at least until I pull it out and play with it again next year).

    Many thanks,
    Michael

    EDIT: Should have investigated further before posting. The solution is even simpler. Neither "SPI.endTransaction()" nor "SPI.beginTransaction()" needed to be called in the routine. All I had to do was move the pinModes from setup to after SPI.end(), which I guess is what KurtE was saying.
    This hobby certainly is a stern lesson about the limits of my brilliance.
    Last edited by Michael Ward; 10-08-2017 at 03:25 PM.

  24. #24
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    42
    An observation, not really a problem.
    I notice that with v1.40 I now have to go back to adding "while (!Serial.available() && millis() < 1500);" to setup. I didn't have to do that with v1.36
    --Michael

  25. #25
    Quote Originally Posted by Michael Ward View Post
    An observation, not really a problem.
    I notice that with v1.40 I now have to go back to adding "while (!Serial.available() && millis() < 1500);" to setup. I didn't have to do that with v1.36
    --Michael
    Indeed - that was changed. There was as much as a 2.5 second wait for Serial to arrive in a couple of builds around v1.36 with Serial.begin(3344);, that was removed because it was causing long start up delays, was a recent thread/post that caused that change in recent release.

    Should be >> "while (!Serial && millis() < 1500);" // where you choose the expected wait time window .

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •