Tiny85 SPI

I'm trying to get my 328p tap tempo code to run on a attiny85
I think spi is not working, read various examples and threads and i'm no wiser
I've added this:

#include <tinySPI.h>            // https://github.com/JChristensen/tinySPI
#define HARDWARE_SPI 1          // set to 1 to use hardware SPI, set to 0 to use shiftOut (software SPI)

and changed some pins:

const int tapbuttonpin = 4; // TINY85 pin 3
int ledpin = 5; // TINY85 pin 1
const int slaveDelayPin = 1; // TINY85 pin 6

and I think I used the same SPI pins I was using with the 328p
is there something else I need to do to get my sketch to work?

Tap_Dual_Tiny85.ino (4.45 KB)

I think I used the same SPI pins I was using with the 328p

That would certainly be something to check carefully.

This looks promising but again I’m not sure what parts to add to my sketch to get it to work:

#include <tinySPI.h> // necessary library
int del=300; // used for various delays

const int LATCH_PIN = 0; //storage register clock (slave select)
const int CLOCK_PIN = 2; //shift register clock
const int DATA_PIN = 1; //data in

void setup(void)
{
//pullups on for unused pins to minimize power consumption
//pinMode(3, INPUT_PULLUP);
//pinMode(4, INPUT_PULLUP);

//set up the pins for software SPI
pinMode(CLOCK_PIN, OUTPUT);
pinMode(DATA_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
digitalWrite(LATCH_PIN, HIGH);
}

void setValue(int value)
{
digitalWrite(LATCH_PIN, LOW);

//SPI.begin();
//SPI.transfer(myByte);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value);

digitalWrite(LATCH_PIN, HIGH);
}

void loop()
{
setValue(255);
delay(del);
setValue(0);
delay(del);
}

What core are you using? You should be using TinyCore, which has native support for SPI so you don't need to use a specific library for it.

using a 328p my tap tempo sketch gives me a blinking led,
using tiny 85 I have a permanently lit led, thats wrong
TinyCore didn't fix the problem either

Let's establish some basics:
When using TinyCore, did you select the correct chip and clock settings, and 'Burn Bootloader'?
What code did you upload when using TinyCore?

Leetut:
using a 328p my tap tempo sketch gives me a blinking led,
using tiny 85 I have a permanently lit led, thats wrong
TinyCore didn't fix the problem either

The schematic you posted doesn't appear to have an LED connected, can you please post an updated schematic that shows the hardware you were using when you were trying TinyCore?

sorry, attached updated code, schematic, board settings

I didn't burn the bootloader

Tap_Dual_Tiny85.ino (4.2 KB)

board settings.png

burned the bootloader, didn't help

I recommend you spend a couple of minutes reading the TinyCore documentation, it'll clear up a few things for you.

Leetut:
burned the bootloader, didn't help

You need to burn the bootloader to set all clock settings etc. I'll assume you did it successfully?

Leetut:
sorry, attached updated code, schematic, board settings

With more than 200 posts you should know how to attach code in your post so that everyone can read it. In case not, here is a helpful guide. Please see point #7.

Your schematic shows the LED connected to Pin 1, which is the RESET pin. You can't use this as an output, this pin needs to be tied high unless you are using a HV programmer.

yeah the code tags, most of my 200 posts were replies to how I post code,
post the full code, attach the full code etc
usually im using too many characters and it won't let me post it in code tags,
anyway pin1 the reset pin, if I can't use it i'm out of pins
need 2 inputs, 1 led output, and the digital pot connection,
I'll try a tiny84 with more pins, thank you for the help

BJHenry:
TinyCore

The core he is using is called ATTinyCore - which is good; it's the core he should be using.

There is ALSO a core called TinyCore (it is not as actively maintained - I don't recall if there was ever a version by that name that supported the '85)

While the tinySPI library and it's ilk should work with my core, you should also be able to just pretend you're on a processor with a real SPI peripheral and use SPI.h, because my core includes a special version of SPI.h that uses the same API as the standard SPI.h, but pulls in the appropriate implementation for the hardware on the selected processor.

As noted, you seem to be trying to use the reset pin as an output; you can't do that, it's the reset pin! While it is possible to configure the reset pin to work as an I/O pin (albeit one with very weak output capability), my core does not support that without manual steps to actually set that fuse, because reprogramming a part once you have done that is quite challenging, and requires an HVSP device, which most people (including myself) do not have, so it would be leaving a trap for novices to brick their parts (besides that, since it has to be set after uploading the code, it violates the principle of "uploading sketch does not change fuses"). It looks to me like the transistor on the reset pin would load down reset, so when the part was in the circuit you describe, it would be held in permanent reset state and do nothing...

You only get 5 usable I/O pins on a tiny85 - your project appears to require 6. Either drop the LED and disconnect that hardware from the reset pin, or it's time to move up to a larger part (eg, a tiny84)

5V---| ledpin moved to 4 // ATTINY85 pin 3
|
3.3K (between 1K and 4.7K should work)
A0---| readingtapbutton = analogRead(A0) > 1000; // ATTINY85 pin 1
10K may require small delays between analogReads
|
/ tap-Button
GND---| (no warranty...)

back with a tiny84,
still struggling to get my code to work correctly,
my pot controls the flashing speed of the led correctly, but not the digipot (SPI?)
tap switch doesn't work, it should also change the flashing speed of the led and the digipot

I originally had this working on a 328p, the board I made was messy so I made another with some pin changes,
that didn't work, couldn't figure out why, so I etched another board with the original pin config, still didn't work, same problems as attempt 2, tried again, same problem again, so I ordered another 328p and some crystals, still waiting for them to arrive 4 weeks later, so I tried using the tiny85 (reset pin!)
and now the tiny84

if anyone can see anything wrong with any of this it would be greatly appreciated

#include <SPI.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#define TOLERANCE 5
int oldVal = 0;


//Variables for LED
int redpin = 8;            // pin 5 tiny84
int currentred = HIGH;
int led_lit_time = 30;

//Variables for the repeat rate of the delay
int digipot_value = 100;
const int min_delay = 100;
const int max_delay = 1000;

int current_ms;

//Variables for "determine pot value"
int value;
int pot_low;
int pot_high;
int pot_value_low;
int pot_value_high;
int interpolated_ms;
int potchangerequired = HIGH;

int startup = HIGH;

//Variablen for tap-Button
const int tapbuttonpin = 5; // TINY84 pin 8
int tapbuttonstate = LOW;
int readingtapbutton;
int lasttapbuttonstate = LOW;

//Variables for Tap-Tempo
long firsttapmillis = 0;
long secondtapmillis = 0;
long tappeddelta = 0;
int firsttap = LOW;

//Variables for LED-blink-freq.
int ledpin = 10; // TINY84 pin 2
int blinkstate = LOW;
long lastblinktoggle;
int blinkfreq;

const int slaveDelayPin = 7; // TINY84 pin 6


//Variables and constants for debounce (global)
long lastDebounceTime = 0;
long debounceDelay = 5;

unsigned long currentMillis;


void setup()
{
  SPI.begin();

  pinMode (slaveDelayPin, OUTPUT);
  pinMode(ledpin, OUTPUT);
  pinMode(redpin, OUTPUT);                                          // Pin for Tap Tempo LED
  pinMode(tapbuttonpin, INPUT_PULLUP);


  lastblinktoggle = millis();

  
}

void loop()
{

  //############### NORMAL POT (DELAY TIME) ######################
  int potVal = analogRead(A1);  // tiny84 pin 12
  int potval_ms = map(potVal, 0, 1023, min_delay, max_delay);
  int diff = abs(potVal - oldVal);

  if (diff > TOLERANCE)
  {
    current_ms = potval_ms;
    potchangerequired = HIGH;
    oldVal = potVal;
  }

  if (startup = HIGH)
  {
    current_ms = potval_ms;
    potchangerequired = HIGH;
    oldVal = potVal;
    startup = LOW;
  }

  //############### TAP-BUTTON ##########################
  readingtapbutton = digitalRead(tapbuttonpin);
  if (readingtapbutton != lasttapbuttonstate)
  {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (readingtapbutton != tapbuttonstate)
    {
      tapbuttonstate = readingtapbutton;
      if (tapbuttonstate == LOW)
      {
        if (firsttap == HIGH)
        {
          lastblinktoggle = current_ms - blinkfreq;
          firsttapmillis = millis();
          firsttap = LOW;
        }
        else
        {
          secondtapmillis = millis();
          tappeddelta = secondtapmillis - firsttapmillis;

          if (tappeddelta <= 1500 && tappeddelta >= min_delay)
          {
            current_ms = tappeddelta;
            tappeddelta = 0;
            potchangerequired = HIGH;
          }
          firsttap = HIGH;
        }
      }
    }
  }
  lasttapbuttonstate = readingtapbutton;

  if (millis() - firsttapmillis > 2000)
  {
    firsttap = HIGH;
  }




  // ############### BLINK according to blinkfreq ########################
  blinkfreq = current_ms;
  currentMillis = millis();
    digitalWrite(redpin, currentred);
  if (currentMillis - blinkfreq > lastblinktoggle)
  {
    digitalWrite(ledpin, HIGH);
    lastblinktoggle = currentMillis;
  }

  if (currentMillis - lastblinktoggle > led_lit_time)
  {
    digitalWrite(ledpin, LOW);
  }

  // ############### WRITE TO DELAY-MCP (POTCHANGEREQUIRED) ########################
  if (potchangerequired == HIGH)
  {
    for (int i = 0; i < 256; i = i + 5)
      // The loop tries to find two values from the EEPROM, that "surround" current_ms

    {
      pot_low = i;
      pot_high = i + 5;
      EEPROM_readAnything(i, pot_value_low);
      EEPROM_readAnything(i + 5, pot_value_high);
      if (current_ms >= pot_value_low && current_ms < pot_value_high)
      {
        digipot_value = pot_low + (((current_ms - pot_value_low) * 100) / (pot_value_high - pot_value_low) * (pot_high - pot_low)) / 100;
        digitalPotWrite(slaveDelayPin, digipot_value);
        potchangerequired = LOW;
      }
    }
  }
}    // END of LOOP()


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ digital pot write ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int digitalPotWrite(int pin, int value)
{
  digitalWrite(pin, LOW);   //When Slave is LOW, the MCP listens to the master
  SPI.transfer(0x11);
  SPI.transfer(value);
  digitalWrite(pin, HIGH);  //When Slave is HIGH, the MCP does not listen to the master
}

upload settings.png

You've made good progress, at least part of the project is working.
Your tap switch is probably not working because you're trying to use one of the USI pins as the input, and you can't do that and use the USI module at the same time. Do this to double-check:

  1. Upload a simple sketch that just reads the tap button and turns the LED on or off depending on the state of the tap button.
  2. Modify the sketch to include SPI.h and the SPI.begin() command, see if the LED still works.

The digipot isn't working because you're using the wrong pin. Although it is labelled 'MOSI', the ATTinyCore documentation has this to say:

Take care to note that the USI does not have MISO/MOSI, it has DI/DO; when operating in master mode, DI is MISO, and DO is MOSI.

DO is PA5.

moved tap input to PA3 (pin 10)
and changed the output to the digipot to PA5 (pin 8 - DO)

no change,
tap button still doesn't change the led flashing speed or the digipot
and like before rotary pot only changes the speed of the led

#include <SPI.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#define TOLERANCE 5
int oldVal = 0;


//Variables for LED
int redpin = 8;            // pin 5 tiny84
int currentred = HIGH;
int led_lit_time = 30;

//Variables for the repeat rate of the delay
int digipot_value = 100;
const int min_delay = 100;
const int max_delay = 1000;

int current_ms;

//Variables for "determine pot value"
int value;
int pot_low;
int pot_high;
int pot_value_low;
int pot_value_high;
int interpolated_ms;
int potchangerequired = HIGH;

int startup = HIGH;

//Variablen for tap-Button
const int tapbuttonpin = 3;           // TINY84 pin 10
int tapbuttonstate = LOW;
int readingtapbutton;
int lasttapbuttonstate = LOW;

//Variables for Tap-Tempo
long firsttapmillis = 0;
long secondtapmillis = 0;
long tappeddelta = 0;
int firsttap = LOW;

//Variables for LED-blink-freq.
int ledpin = 10;                            // TINY84 pin 2
int blinkstate = LOW;
long lastblinktoggle;
int blinkfreq;

const int slaveDelayPin = 7; // TINY84 pin 6


//Variables and constants for debounce (global)
long lastDebounceTime = 0;
long debounceDelay = 5;

unsigned long currentMillis;


void setup()
{
  SPI.begin();

  pinMode (slaveDelayPin, OUTPUT);
  pinMode(ledpin, OUTPUT);
  pinMode(redpin, OUTPUT);                                          // Pin for Tap Tempo LED
  pinMode(tapbuttonpin, INPUT_PULLUP);


  lastblinktoggle = millis();

  
}

void loop()
{

  //############### NORMAL POT (DELAY TIME) ######################
  int potVal = analogRead(A1);  // tiny84 pin 12
  int potval_ms = map(potVal, 0, 1023, min_delay, max_delay);
  int diff = abs(potVal - oldVal);

  if (diff > TOLERANCE)
  {
    current_ms = potval_ms;
    potchangerequired = HIGH;
    oldVal = potVal;
  }

  if (startup = HIGH)
  {
    current_ms = potval_ms;
    potchangerequired = HIGH;
    oldVal = potVal;
    startup = LOW;
  }

  //############### TAP-BUTTON ##########################
  readingtapbutton = digitalRead(tapbuttonpin);
  if (readingtapbutton != lasttapbuttonstate)
  {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (readingtapbutton != tapbuttonstate)
    {
      tapbuttonstate = readingtapbutton;
      if (tapbuttonstate == LOW)
      {
        if (firsttap == HIGH)
        {
          lastblinktoggle = current_ms - blinkfreq;
          firsttapmillis = millis();
          firsttap = LOW;
        }
        else
        {
          secondtapmillis = millis();
          tappeddelta = secondtapmillis - firsttapmillis;

          if (tappeddelta <= 1500 && tappeddelta >= min_delay)
          {
            current_ms = tappeddelta;
            tappeddelta = 0;
            potchangerequired = HIGH;
          }
          firsttap = HIGH;
        }
      }
    }
  }
  lasttapbuttonstate = readingtapbutton;

  if (millis() - firsttapmillis > 2000)
  {
    firsttap = HIGH;
  }




  // ############### BLINK according to blinkfreq ########################
  blinkfreq = current_ms;
  currentMillis = millis();
    digitalWrite(redpin, currentred);
  if (currentMillis - blinkfreq > lastblinktoggle)
  {
    digitalWrite(ledpin, HIGH);
    lastblinktoggle = currentMillis;
  }

  if (currentMillis - lastblinktoggle > led_lit_time)
  {
    digitalWrite(ledpin, LOW);
  }

  // ############### WRITE TO DELAY-MCP (POTCHANGEREQUIRED) ########################
  if (potchangerequired == HIGH)
  {
    for (int i = 0; i < 256; i = i + 5)
      // The loop tries to find two values from the EEPROM, that "surround" current_ms

    {
      pot_low = i;
      pot_high = i + 5;
      EEPROM_readAnything(i, pot_value_low);
      EEPROM_readAnything(i + 5, pot_value_high);
      if (current_ms >= pot_value_low && current_ms < pot_value_high)
      {
        digipot_value = pot_low + (((current_ms - pot_value_low) * 100) / (pot_value_high - pot_value_low) * (pot_high - pot_low)) / 100;
        digitalPotWrite(slaveDelayPin, digipot_value);
        potchangerequired = LOW;
      }
    }
  }
}    // END of LOOP()


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ digital pot write ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int digitalPotWrite(int pin, int value)
{
  digitalWrite(pin, LOW);   //When Slave is LOW, the MCP listens to the master
  SPI.transfer(0x11);
  SPI.transfer(value);
  digitalWrite(pin, HIGH);  //When Slave is HIGH, the MCP does not listen to the master
}

I can't see anything obvious after a quick readthrough of your code. Your best bet would be to write a real simple sketch that just turns the LED on or off depending on the state of the switch. That'll give you an indication as to where the problem lies- either with code or hardware.