Having problem porting code from Uno to ATtiny85

deleted

Some more notes

I’ve tried several chips and triple checked my circuit.

I’ve tried compiling this with both of these
From Unofficial list of 3rd party boards support urls · arduino/Arduino Wiki · GitHub

ATtiny: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json

ATtiny45 / ATtiny85 and ATtiny44 / ATtiny84 support
ATtiny: http://drazzy.com/package_drazzy.com_index.json

ATtiny25/45/85, 24/44/85, 261/461/861, 87/167, 48/88, 2313/4313
ATtiny441/841, 1634, 828 (optiboot support on 841/1634/828)

Have you tried writing/running a simple example, without all of the excess baggage, that just moves the servo back and forth continuously?

/ Have no idea what this section is.

The way the servo library works, you need to call myservo.write() to set the position, and then you have call myservo.refresh() "frequently" (about every 20ms) to send new pulses to the servo motor that actually keep it in position.
The code that you don't understand makes this refresh happen automatically, rather than needing to be done inside loop.

I don't quite understand the program logic, and it isn't very well commented. Especially, I'm not sure what your "averaging" code is actually averaging, and ... shouldn't servo_direction CHANGE somewhere?

Thank you guys for the replys.

Here is the code a little better commented. Some of the averaging stuff was left over from a more complicated script. I was trying to simplify it in hopes that maybe I was overflowing a variable. Before/ with the script that works great on the UNO it would just add up 10 analog reads from both left and right then divide them by the number of reads. I was afraid this number was getting to big for the attiny so I changed it to a +1 if signal is stronger for one than the other.

As it sits. It takes 10 samples. If left is greater than right left gets a +1 and vise versa. After 10 samples I should have something like 8 for left and 2 for right (just simple example) Since left is stronger than it moves the position of the servo by an increment. and turns on some indicator lights.

As it is now it doesn't matter what the antenna inputs are the servo drives to one direction with the light for that direction on and just stays there. I'm going to comment the code a little more and include it in the next post. Let me knwo if you have any other questions.

I tried to comment the code a bit more. Let me know if you have any questions. Should be straight forward. Take 10 samples. The side that was strongest for those 10 samples move the servo in particular direction. Problem is I can force one side higher and it doesn’t matter… Servo still drives one way.

#include <Adafruit_SoftServo.h>


Adafruit_SoftServo myservo;            // create servo object to control a servo 

// Define Variables 
int numReadings = 10;     // Number of reads to buff analog signal


int input_pin_antennaleft = 2;   // input pin for left signal
int input_pin_antennaright = 4;  // input pin for right signal
int indicator_light_left = 1;    // left is stronger indicator light
int indicator_light_right = 3;   // right is stronger indicator light


int pos = 90;              // variable to store the servo start position
int posinc = 1;            // Servo increment in degrees
int posinc = 1;            // Servo increment 
int servo_direction = 1;   // Set to 1 or -1 to reverse servo direction

int start_delay = 200;     // Pause at start up to let servo center.


int posmax = 102;          // Servo position travel max in degrees
int posmin = 78;           // Servo position travel min in degrees
int bound_hysteriesis = 5; // Back off max/min by this much

int avgleft = 0;          // Buffed antenna reads
int avgright = 0;         // Buffed antenna reads


 

                           

void setup() //runs once
{

  
/////////////////////////// Have no idea what this section is. Servo will not run without it. 
  OCR0A = 0xAF;            // any number is OK
  TIMSK |= _BV(OCIE0A);    // Turn on the compare interrupt (below!)
/////////////////////////// Have no idea what this section is. Servo will not run without it.  
  
  
  myservo.attach(0);       // attaches the servo on pin 0 to the servo object 

  int pos = 90;             // Start with servo centered
  myservo.write(pos);       
  delay(start_delay);       // Start up delay to allow servo to center.

}

void loop() {  //runs non stop
     
      
      
      avgleft = 0;          // Start by clearing buffers left
      avgright = 0;         // Start by clearing buffers right



      
    for (int i=0; i <= numReadings; i++){                           // number of samples to take to buffer the signals
        
            
            if (analogRead(input_pin_antennaleft) > analogRead(input_pin_antennaright))
                      { 
                          avgleft = avgleft + 1;}                 // if left side on this sample is greater add 1 to left side "is best" counter
            
            if (analogRead(input_pin_antennaright) > analogRead(input_pin_antennaleft)) 
                      { 
                         avgright = avgright + 1;}              // if right side on this sample is greater add 1 to right side "is best" counter
            
      
      delay(1);
  }
    
  
if (avgleft > avgright){                                            // If left is stronger set direction by posinc  
    posinc = -1 * servo_direction;
    digitalWrite(indicator_light_left, HIGH); 
    digitalWrite(indicator_light_right, LOW); 
  }
  
  if (avgright > avgleft){                                         // If right is stronger set direction by posinc
    posinc = 1 * servo_direction;
    digitalWrite(indicator_light_left, LOW); 
    digitalWrite(indicator_light_right, HIGH); 
  }
 

pos = pos + posinc;                                                // save new position...  So old position is being updated by the direction to move.



if (pos > posmax){                                                // If near limits back off by hysterisis 
pos = posmax - bound_hysteriesis;
}

if (pos < posmin){
pos = posmin + bound_hysteriesis;
}

   myservo.write(pos);                                            //Send new position to servo
   delay(1);

   
   

   
  

} 


/////////////////////////// Have no idea what this section is. Servo will not run without it. 

// We'll take advantage of the built in millis() timer that goes off
// to keep track of time, and refresh the servo every 20 milliseconds
volatile uint8_t counter = 0;
SIGNAL(TIMER0_COMPA_vect) {
  // this gets called every 2 milliseconds
  counter += 2;
  // every 20 milliseconds, refresh the servos!
  if (counter >= 20) {
    counter = 0;
    myservo.refresh();
   
  }
}
/////////////////////////// Have no idea what this section is. Servo will not run without it.

So I’ll try asking again:-
Have you tried writing/running a simple example, without all of the excess baggage, that just moves the servo back and forth continuously? (Like the ‘Sweep’ example that comes with the IDE.)

What I’m getting at is have you eliminated the possibility that it’s a hardware problem? The problem that you describe often happens when the servo signal pin is not driven at all.

Also, have you tried placing serial debugging lines in the code, to help sort out exactly where things are going wrong?

All of that extra white space in your program makes it much harder to read, too, and serves no useful purpose.
It should look more like this:-

#include <Adafruit_SoftServo.h>

Adafruit_SoftServo myservo;         // create servo object to control a servo

// Define Variables
int numReadings = 10;               // Number of reads to buff analog signal
int input_pin_antennaleft = 2;      // input pin for left signal
int input_pin_antennaright = 4;     // input pin for right signal
int indicator_light_left = 1;       // left is stronger indicator light
int indicator_light_right = 3;      // right is stronger indicator light
int pos = 90;                       // variable to store the servo start position
int posinc = 1;                     // Servo increment in degrees
int posinc = 1;                     // Servo increment
int servo_direction = 1;            // Set to 1 or -1 to reverse servo direction
int start_delay = 200;              // Pause at start up to let servo center.
int posmax = 102;                   // Servo position travel max in degrees
int posmin = 78;                    // Servo position travel min in degrees
int bound_hysteriesis = 5;          // Back off max/min by this much
int avgleft = 0;                    // Buffed antenna reads
int avgright = 0;                   // Buffed antenna reads

void setup() //runs once
{
    /////////////////////////// Have no idea what this section is. Servo will not run without it.
    OCR0A = 0xAF;                   // any number is OK
    TIMSK |= _BV(OCIE0A);           // Turn on the compare interrupt (below!)
    /////////////////////////// Have no idea what this section is. Servo will not run without it.

    myservo.attach(0);              // attaches the servo on pin 0 to the servo object
    int pos = 90;                   // Start with servo centered
    myservo.write(pos);
    delay(start_delay);             // Start up delay to allow servo to center.
}

void loop()    //runs non stop
{
    avgleft = 0;                    // Start by clearing buffers left
    avgright = 0;                   // Start by clearing buffers right
    for (int i = 0; i <= numReadings; i++)  // number of samples to take to buffer the signals
    {
        if (analogRead(input_pin_antennaleft) > analogRead(input_pin_antennaright))
        {
            avgleft = avgleft + 1;
        }               // if left side on this sample is greater add 1 to left side "is best" counter

        if (analogRead(input_pin_antennaright) > analogRead(input_pin_antennaleft))
        {
            avgright = avgright + 1;
        }              // if right side on this sample is greater add 1 to right side "is best" counter
        delay(1);
    }
    
    if (avgleft > avgright)                         // If left is stronger set direction by posinc
    {
        posinc = -1 * servo_direction;
        digitalWrite(indicator_light_left, HIGH);
        digitalWrite(indicator_light_right, LOW);
    }
    
    if (avgright > avgleft)                         // If right is stronger set direction by posinc
    {
        posinc = 1 * servo_direction;
        digitalWrite(indicator_light_left, LOW);
        digitalWrite(indicator_light_right, HIGH);
    }
    
    pos = pos + posinc; // save new position...  So old position is being updated by the direction to move.
    if (pos > posmax)                               // If near limits back off by hysterisis
    {
        pos = posmax - bound_hysteriesis;
    }
    if (pos < posmin)
    {
        pos = posmin + bound_hysteriesis;
    }
    myservo.write(pos);                             //Send new position to servo
    delay(1);
}

/////////////////////////// Have no idea what this section is. Servo will not run without it.
// We'll take advantage of the built in millis() timer that goes off
// to keep track of time, and refresh the servo every 20 milliseconds
volatile uint8_t counter = 0;
SIGNAL(TIMER0_COMPA_vect)
{
    // this gets called every 2 milliseconds
    counter += 2;
    // every 20 milliseconds, refresh the servos!
    if (counter >= 20)
    {
        counter = 0;
        myservo.refresh();
    }
}
/////////////////////////// Have no idea what this section is. Servo will not run without it.

If you want people to help, you need to make it as easy as possible for them to do so.

If, as you say, this code works “fantastically” on your UNO, then the code itself probably isn’t the problem, so I haven’t put any time into trying to decipher it. I’m inclined to think you have a hardware issue.

So I'll try asking again:-
Have you tried writing/running a simple example, without all of the excess baggage, that just moves the servo back and forth continuously? (Like the 'Sweep' example that comes with the IDE.)

What I'm getting at is have you eliminated the possibility that it's a hardware problem? The problem that you describe often happens when the servo signal pin is not driven at all.

Yes seems to work just fine

Also, have you tried placing serial debugging lines in the code, to help sort out exactly where things are going wrong?

Attiny85 does not support this. I hope I'm wrong about that but I'm 99% certain it does not. There are a lot of things that Attiny85 does not support which is why I believe it is not working.

All of that extra white space in your program makes it much harder to read, too, and serves no useful purpose.

OK Didn't know extra spaces made it tough to read. I'll make it more dense next time. Personally I like to see things grouped together but hey... your the boss..

If you want people to help, you need to make it as easy as possible for them to do so.

If, as you say, this code works "fantastically" on your UNO, then the code itself probably isn't the problem, so I haven't put any time into trying to decipher it. I'm inclined to think you have a hardware issue.

Sorry to bother you. There are a lot of things that work on UNO but not Attiny85. For instance the arduino's servo library. I've tried all I can short of rebuilding the schematic again and writing the code with a different approach. That is why I was hoping to find some help here.

nosredna000:
Yes seems to work just fine

Attiny85 does not support this. I hope I'm wrong about that but I'm 99% certain it does not. There are a lot of things that Attiny85 does not support which is why I believe it is not working.

Of course - my bad. I just got up and am half asleep. (I use ATtiny's myself, so already know this.)

OK Didn't know extra spaces made it tough to read. I'll make it more dense next time. Personally I like to see things grouped together but hey... your the boss..

No, I'm not the boss at all.

And I don't consider this "grouped together":-

myservo.write(pos);                                            //Send new position to servo
   delay(1);

   
   

   
 

}

8 lines after the last line of code here before the closing bracket - very easy to miss the bracket. And there's nothing wrong with grouping things together, but they don't need to be spaced this far apart, do they? :-

}
 

pos = pos + posinc;                                                // save new position...  So old position is being updated by the direction to move.



if (pos > posmax)

Sorry to bother you. There are a lot of things that work on UNO but not Attiny85. For instance the arduino's servo library. I've tried all I can short of rebuilding the schematic again and writing the code with a different approach. That is why I was hoping to find some help here.

Yes, again because I was half asleep - I meant to mention that it could be not just a hardware issue, but an issue with using that particular library.

If the code works fine on the UNO, and the servo works on the ATtiny85 using that adafruit library, then obviously something else is amiss, and rewriting the code with a different approach may leave you right where you are now.
You haven't mentioned what you're using as the sensors that you call antennae.
You also haven't shown us your schematic diagram.
Without the full picture, we're partly in the dark.

Edit: Just one other point - have you tried reading pots on each of the two analogue pins that you're using for antannae, in turn, and dimming a LED or something, to make sure you're connected to the right pins and that aspect of the project is working OK?
These are the ATtiny85 pin mappings from David Mellis' cores, copied from his pins_arduino.h file:-

//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

You have the pin numbers defined as 2 and 4 in your code.

westfw:
I don't quite understand the program logic, and it isn't very well commented. Especially, I'm not sure what your "averaging" code is actually averaging, and ... shouldn't servo_direction CHANGE somewhere?

The servo reversing happens here. The servo-direction is just incase the servo operates in the wrong direction. It reverses by multiplying by a negative number. I was trying to make it easier for people to use the code and just change stuff at the top to match thier setup.

again the averageing was left over from a previous script. I was afraid I was overflowing it by adding up 10 analog reads so I changed how it worked to avgleft a 1 if it was greater and viseversa. No dice. Still bad

I had this same problem when I was using int instead of long on the UNO script and was counting like a 100 samples at a time. It would overflow INT and drive the servo into a corner.

  if (avgleft > avgright)                         // If left is stronger set direction by posinc
    {
        posinc = -1 * servo_direction;
        digitalWrite(indicator_light_left, HIGH);
        digitalWrite(indicator_light_right, LOW);
    }
    
    if (avgright > avgleft)                         // If right is stronger set direction by posinc
    {
        posinc = 1 * servo_direction;
        digitalWrite(indicator_light_left, LOW);
        digitalWrite(indicator_light_right, HIGH);
    }

nosredna000:
....I was trying to make it easier for people to use the code and just change stuff at the top to match thier setup.

What people? You're just starting out and trying to write example code for others?
This is not good example code - there are easier ways.

And I just edited my last post, with more info relating to the analogue pins.

OldSteve:
Yes, again because I was half asleep - I meant to mention that it could be not just a hardware issue, but an issue with using that particular library.

If the code works fine on the UNO, and the servo works on the ATtiny85 using that adafruit library, then obviously something else is amiss, and rewriting the code with a different approach may leave you right where you are now.
You haven't mentioned what you're using as the sensors that you call antennae.
You also haven't shown us your schematic diagram.
Without the full picture, we're partly in the dark.

Ha, why I'm here..

The sensors i'm reading are just two 0-1v outputs from recievers. They sink to a 100k resistor to ground with the attiny reading just before the resistor. Measureing at the ATtiny I see between 300mv and 800mv on either input. The servo signal wire is attached directly to the Attiny. I've tried other servos to see if that was the problem. no dice. The whole thing is powered by a 5v 5amp UBEC BEC (basically switching regulator). Output on the BEC measures about 5.25v

Here is a video of MY UNO version working quite flawlessly with the stock arduino servo library. You can see the idea. Reads two antennas, see which is hotter, steers servo to point reciever in that direction.

OK I get it. I'm a terrible coder and shouldn't be allowed to help anyone with this..

one analog input is on PB2 or normal DIP8 naming pin7
other is on PB4 or normal DIP8 naming pin 3

nosredna000:
Here is a video of MY UNO version working quite flawlessly with the stock arduino servo library. You can see the idea. Reads two antennas, see which is hotter, steers servo to point reciever in that direction.

Simple Arduino powered antenna tracker. - YouTube

I'm not interesting in watching videos.

And you were misleading. You said "This code works fantastically on my UNO".
If you used a different library, it's not the same code.

And it also means that you din't use this:-

   /////////////////////////// Have no idea what this section is. Servo will not run without it.
    OCR0A = 0xAF;                   // any number is OK
    TIMSK |= _BV(OCIE0A);           // Turn on the compare interrupt (below!)
    /////////////////////////// Have no idea what this section is. Servo will not run without it.

or this:-

/////////////////////////// Have no idea what this section is. Servo will not run without it.
// We'll take advantage of the built in millis() timer that goes off
// to keep track of time, and refresh the servo every 20 milliseconds
volatile uint8_t counter = 0;
SIGNAL(TIMER0_COMPA_vect)
{
    // this gets called every 2 milliseconds
    counter += 2;
    // every 20 milliseconds, refresh the servos!
    if (counter >= 20)
    {
        counter = 0;
        myservo.refresh();
    }
}
/////////////////////////// Have no idea what this section is. Servo will not run without it.

you need to be accurate if you really want to sort out the problem. I've been basing my assumptions on the fact that you said that this code works on an Arduino, when in reality you've never tested it on one.

Also did you read my comment on the ATtiny85 analogue pins?

So... I should run a library that will not run on UNO... for what reason? The adafruit library is specifically for the attiny stuff. Do you know of a servo library that will run out of the box for both uno and attiny?

nosredna000:
So... I should run a library that will not run on UNO...

adafruit actually say that it will run on a UNO, with correct pin mappings.

And based on that, my point was that you shouldn't have said that your code runs on a UNO when you hadn't tested it on one.

Anyway, I'll leave you to it. I'm sure you'll figure out what's wrong.

It WOULD be helpful to see the code that "works" on Uno, if it is significantly different than the tiny85 code (and I guess it is...)

It might be possible to run code very similar to this t85 code on your Uno (ie using the same SW Servo library and timer hack), where it would be much easier to debug. (Even if that means running "inferior" code on the Uno.)