Go Down

Topic: Converting from Arduino Uno to ATTiny85 (Read 2830 times) previous topic - next topic

technicallyartistic

So I am trying to make a scale that when it weighs something within a certain range a serve re-positions its self.  I'm using an HX711 for the scale part.  I've got the code working on the Arduino  Uno, but not so much luck getting it to work on the AtTiny85.  I'm fairly new to this so I'm not sure what exactly I'm doing if there's not at least part of a tutorial to follow.

I can program they AtTiny85 using the Arudino as ISP and have gotten the blink example code over then are working at least.

More my problem is that the code I had working on the Uno doesn't seem to fly when getting uploaded to the AtTiny85.  It wont even compile it seems like.  I tried taking all the serial code out of there since I don't need to see that and thought it was maybe something the AtTiny85 couldn't do.


Anyway, the original working Uno code is:
Code: [Select]
/*

 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/

#include "HX711.h"
#include <Servo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  2
#define CLK  3

HX711 scale(DOUT, CLK);
Servo lidservo; //decalre the servo is "lidservo"
 float average; //decalare floating point variable "average"

void setup() {
  Serial.begin(9600);
  Serial.println("measuring cat weight");
  lidservo.attach (9);

  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0


  Serial.println("Readings:");
}

void loop() {
  Serial.print("Reading: ");
  //Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"
    Serial.println(average);
  Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();


  if ( average > 7&&average < 10)
    {
    lidservo.writeMicroseconds (1700);
   
    }
  else
    {
    lidservo.writeMicroseconds (750);

    }

}



I tried uploading this to the AtTiny85:
Code: [Select]
/*

 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/

#include "HX711.h"
#include <Servo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  4
#define CLK  3

HX711 scale(DOUT, CLK);
Servo lidservo; //decalre the servo is "lidservo"
 float average; //decalare floating point variable "average"

void setup() {

  lidservo.attach (1);

  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

}

void loop() {

  //Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"

  if ( average > 7&&average < 10)
    {
    lidservo.writeMicroseconds (1700);
   
    }
  else
    {
    lidservo.writeMicroseconds (750);

    }

}


But I get this error:
Code: [Select]
Arduino: 1.6.5 (Windows 8.1), Board: "ATtiny, ATtiny85, 1 MHz (internal)"

C:\Program Files (x86)\Arduino\libraries\Servo\src\avr\Servo.cpp: In function 'void __vector_3()':
C:\Program Files (x86)\Arduino\libraries\Servo\src\avr\Servo.cpp:82:44: error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'volatile uint16_t* {aka volatile unsigned int*}' for argument '2' to 'void handle_interrupts(timer16_Sequence_t, volatile uint16_t*, volatile uint16_t*)'
   handle_interrupts(_timer1, &TCNT1, &OCR1A);
                                            ^
C:\Program Files (x86)\Arduino\libraries\Servo\src\avr\Servo.cpp: In function 'void initISR(timer16_Sequence_t)':
C:\Program Files (x86)\Arduino\libraries\Servo\src\avr\Servo.cpp:129:5: error: 'TCCR1B' was not declared in this scope
     TCCR1B = _BV(CS11);     // set prescaler of 8
     ^
C:\Program Files (x86)\Arduino\libraries\Servo\src\avr\Servo.cpp:136:5: error: 'TIFR1' was not declared in this scope
     TIFR1 |= _BV(OCF1A);     // clear any pending interrupts;
     ^
C:\Program Files (x86)\Arduino\libraries\Servo\src\avr\Servo.cpp:137:5: error: 'TIMSK1' was not declared in this scope
     TIMSK1 |=  _BV(OCIE1A) ; // enable the output compare interrupt
     ^
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.


I'm guessing this is probably related to the clock stuff for the HX711 since it seems to use some libraries I had to install, but I'm flying a little blind here at the moment.  Any help would be greatly appreciated.

Coding Badly


Riva

#2
Aug 31, 2015, 09:52 am Last Edit: Aug 31, 2015, 09:53 am by Riva
This will explain why it does not compile and alternative options to get your sketch working.

EDIT: Here is another alternative.
Don't PM me for help as I will ignore it.

technicallyartistic

Coding Badly > Because it seems like a simple project and I'd rather use one of these AtTiny85s I have at $2 a piece vs the $20 Arduino Uno.  It'd also be more compact to house.

Riva> Thanks for that.  It seems like I've got to change up the code between the servo and the hx711 I'm using and it's library.  I found this guy that made a scale using an AtTiny85 so I'm going to see if I can hack together something between the two with my limited understanding.

https://makingthingswork.wordpress.com/category/electronics/attiny/

DrAzzy

Your problem is the servo library - there are definitely servo libraries that work with the 85. Find one and use it.

In any event, you do know that you can get Arduino Pro Mini clones on ebay for like $2-3 right?
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy



technicallyartistic

Yeah, I just found that servo library.  Reading the other stuff that sounded like the issue.  I'm just trying to figure out how to impliment it now.  I'm still getting the same error even with that library installed.

technicallyartistic

Ok.  So I'm getting an hour or two in on this project a night.  I sorta got the software servo code working.  I realized how to update the chip to 8mhz and got it running a lot smoother instead of clock ticks that petered out like at first.  But I still don't really understand how to control the start and stop angle like in the code I had before.  This is my test code for the servo which just has it bouncing back and forth but I don't really understand how the steps and the delay control the final stopping position. (This it the same code from the thread with the Italian guy.

Code: [Select]
#include <SoftwareServo.h>

SoftwareServo servo;

void setup()
{
  servo.attach(3);}

void loop() {
    int pos;
    for(pos = 0; pos < 180; pos += 10) {
        servo.write(pos);             
        delay(10);                     
        SoftwareServo::refresh();//this row....
    }
    for(pos = 180; pos>=1; pos-=10) {                               
        servo.write(pos);             
        delay(10);                     
        SoftwareServo::refresh();//This row....
    }
}

technicallyartistic

Ok, so I figured out I could have it just write any integer and if it wasn't ping ponging back and forth it would just go there.  So I was just uploading the code with one write position it would go there, upload with another write position, it would go there.   That seemed to work on it's own.  So I tried to apply that to the scale code and... it kinda works?  It seems like the servo is always trying to tick like a clock that can't go any further and it is much more jittery in it's turning and it eventual seems to just peter of of energy and wont go back and forth any more when weight is applied to the scale without some sort of reset.

Anybody happen to know what I am doing wrong?

Code: [Select]
/*

 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/

#include "HX711.h"
#include <SoftwareServo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  1
#define CLK  4

SoftwareServo servo;
HX711 scale(DOUT, CLK);
 float average; //decalare floating point variable "average"

void setup() {

  servo.attach (3);

  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

}

void loop() {
 
  average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"

  if ( average > 7&&average < 10)
    {
       
        servo.write(0);             
        delay(15);                     
        SoftwareServo::refresh();//this row....
       
   
    }
  else
    {
                       
        servo.write(90);             
        delay(15);                     
        SoftwareServo::refresh();//this row....

    }

}

Riva

I suspect the problem is with this servo library you need to call refresh() at least every 20ms and the scale.get_units() is taking longer. Try a different servo library or change you code so it does not read the scales every pass through loop. Do you really need to read the scales so fast (about 50 times a second)
Don't PM me for help as I will ignore it.

technicallyartistic

I ordered an Arduino Mini pro last night.  Hopefully that'll be a little more user friendly for what I am doing here.   I just had a bunch of AtTiny85s from another project so I figured I would use them if I could, but that's becoming a whole different struggle to figure out how to get it to run smoothly.  At least with how familiar I am with this stuff.  The other libraries I've looked at don't seem to work with Arduino.

Riva

Code is untested but does this work/help?

Code: [Select]
/*
 
  Arduino pin 2 -> HX711 CLK
  3 -> DAT
  5V -> VCC
  GND -> GND
 
  The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/

#include "HX711.h"
#include <SoftwareServo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  1
#define CLK  4

SoftwareServo servo;
HX711 scale(DOUT, CLK);

byte counter = 0;

void setup() {
 
  servo.attach (3);
 
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0
 
}

void loop() {
 
  if (counter++ > 50){ // Only read scale every 50 passes through loop
    float average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"
    counter = 0;
  }
 
  if ( average > 7 && average < 10){
    servo.write(0);             
  }
  else{
    servo.write(90);             
  }
  delay(15);                     
  SoftwareServo::refresh();//this row....
 
}
Don't PM me for help as I will ignore it.

technicallyartistic

#13
Sep 04, 2015, 05:54 am Last Edit: Sep 04, 2015, 06:18 am by technicallyartistic
Awesome.  That does work.  I had to move the line that defines the float as "average" to before the if statement, but that works consistently, though a little jumpy, I'm guessing from the reduced resolution of running at 8hz.

So while that works, the servo ticks away like a running idling motor in either position  (It's not moving the arm, it just sounds like that).    Is there a way to make it sit there and tell it not to do anything after that until something changes?   Hmmm.  Could I do a duel statement that says if the servo is in that position as well as the scale reads this?

aarg

Is there a way to make it sit there and tell it not to do anything after that until something changes?
Add hysteresis.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

Go Up