3

I have a lot of Raspberry Pi's laying around, so I want to use those to program my attiny85 chips. The problem is that most of the code examples, libraries, and documentation out there assume you're using Arduino. Can I run Arduino commandline software on my Raspberry Pi, and use that to program the attiny85?

I'm trying to compile an RF24 program for the attiny using avr-g++, but I'm running into too many dependency errors, and I wonder if things will just be easier if I use Arduino software.`

asked Apr 15, 2017 at 23:18
4
  • 1
    I would suggest that things might be easier if you don't use the Arduino software. The AVR toolchain should work well in just about any *nix environment, as well as the command line programming tools. Commented Apr 16, 2017 at 2:00
  • The answer is s simple and plain yes. I know this is not a very useful answer, but you did not provide enough details about your problem to enable people to write useful answers. Commented Apr 16, 2017 at 7:25
  • Can I run Arduino commandline software on my Raspberry Pi? - what command line software are you referring to? The Arduino IDE has a GUI interface. Commented Apr 16, 2017 at 7:29
  • 2
    By "program the attiny85", do you mean "upload an already build program to the attiny85" or do you mean "build an executable program for attiny85 from source code", or both? Commented Apr 16, 2017 at 8:00

3 Answers 3

3

Why wouldn't you be able to?

The compiler runs on the computer, not on the Arduino board. You don't need a board to be connected to compile either. If you enable verbose output during compile in the Arduino IDE settings it will tell you where it puts the resulting .hex file, after which you can use avr-dude to upload it to the target MCU.

If you want to use Arduino libraries you'll need to use an core for ATTiny devices (e.g. ATTinyCore). But either way you don't need an Arduino board to compile.


I'd also echo what @Marcus says, for the small devices you are better off completely ditching the Arduino stuff (it's such badly written, bloated, and inefficient), and simply starting with a nice clean C file.

There is nothing stopping you using the Arduino IDE or the avr-libc tools which it uses. If you add your own main() function in a C file and don't put anything in the .ino file you will be able to compile without any of the bloat.

answered Apr 15, 2017 at 23:28
0

"Arduino" makes a statement on the mcu in use.

Technologically, it's extremely unlikely you could run most sketches on devices with less than 1kB of RAM (largest SRAM in Attiny85 is 512 B; most models are smaller).

So, no. The idea "microcontrollers are by now capable enough to run a C++ subset on them directly" behind arduino simply doesn't seem to apply to the Attiny85.

However, there's the "cuteduino", which actually should work with a small set of basic Arduino libraries. It's based on the Attiny85.

I'd argue that you simply don't want to use Arduino on Attinies; these devices are so resource-constrained, that you probably want to keep in control.

Now, the RF24 lib comes with non-arduino attiny85 support, so go for that? http://tmrh20.github.io/RF24/ATTiny.html

answered Apr 15, 2017 at 23:27
0

You can disregard the answers that say you can't compile for the ATtiny85 using the Arduino IDE. I have done so many times, for example my torch locator project which uses the ATtiny85 and the Arduino IDE to compile for it.

Here's my "board":

Torch locator (1)

View from other side:

Torch locator (2)

Code:

// ATtiny85 torch detector
// Author: Nick Gammon
// Date: 25 February 2015
// ATMEL ATTINY 25/45/85 / ARDUINO
// Pin 1 is /RESET
//
// +-\/-+
// 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
// +----+
/*
 Pin 2 (PB3) <-- LDR (GL5539) --> Pin 7 (PB2) <----> 56 k <----> Gnd
 Pin 5 (PB0) <---- LED ---> 100 R <-----> Gnd
*/
#include <avr/sleep.h> // Sleep Modes
#include <avr/power.h> // Power management
#include <avr/wdt.h> // Watchdog timer
const byte LED = 0; // pin 5 
const byte LDR_ENABLE = 3; // pin 2
const byte LDR_READ = 1; // Ain1 (PB2) pin 7
const int LIGHT_THRESHOLD = 200; // Flash LED when darker than this
 // when ADC completed, take an interrupt 
EMPTY_INTERRUPT (ADC_vect);
// Take an ADC reading in sleep mode (ADC)
float getReading (byte port)
 {
 power_adc_enable() ;
 ADCSRA = bit (ADEN) | bit (ADIF); // enable ADC, turn off any pending interrupt
 // set a2d prescale factor to 128
 // 8 MHz / 128 = 62.5 KHz, inside the desired 50-200 KHz range.
 ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); 
 if (port >= A0)
 port -= A0;
#if defined(__AVR_ATtiny85__) 
 ADMUX = (port & 0x07); // AVcc 
#else 
 ADMUX = bit (REFS0) | (port & 0x07); // AVcc 
#endif
 noInterrupts ();
 set_sleep_mode (SLEEP_MODE_ADC); // sleep during sample
 sleep_enable(); 
 // start the conversion
 ADCSRA |= bit (ADSC) | bit (ADIE);
 interrupts ();
 sleep_cpu (); 
 sleep_disable ();
 // reading should be done, but better make sure
 // maybe the timer interrupt fired 
 // ADSC is cleared when the conversion finishes
 while (bit_is_set (ADCSRA, ADSC))
 { }
 byte low = ADCL;
 byte high = ADCH;
 ADCSRA = 0; // disable ADC
 power_adc_disable();
 return (high << 8) | low;
 } // end of getReading
// watchdog interrupt
ISR (WDT_vect) 
{
 wdt_disable(); // disable watchdog
} // end of WDT_vect
#if defined(__AVR_ATtiny85__) 
 #define watchdogRegister WDTCR
#else
 #define watchdogRegister WDTCSR
#endif
void setup ()
 {
 wdt_reset(); 
 pinMode (LED, OUTPUT);
 pinMode (LDR_ENABLE, OUTPUT);
 ADCSRA = 0; // turn off ADC
 power_all_disable (); // power off ADC, Timer 0 and 1, serial interface
 } // end of setup
void loop ()
 {
 // power up the LDR, take a reading
 digitalWrite (LDR_ENABLE, HIGH);
 int value = getReading (LDR_READ);
 // power off the LDR
 digitalWrite (LDR_ENABLE, LOW);
 // if it's dark, flash the LED for 2 mS
 if (value < LIGHT_THRESHOLD)
 {
 power_timer0_enable ();
 delay (1); // let timer reach a known point
 digitalWrite (LED, HIGH);
 delay (2); 
 digitalWrite (LED, LOW);
 power_timer0_disable ();
 }
 goToSleep ();
 } // end of loop
void goToSleep ()
 {
 set_sleep_mode (SLEEP_MODE_PWR_DOWN);
 noInterrupts (); // timed sequence coming up
 // pat the dog
 wdt_reset(); 
 // clear various "reset" flags
 MCUSR = 0; 
 // allow changes, disable reset, clear existing interrupt
 watchdogRegister = bit (WDCE) | bit (WDE) | bit (WDIF);
 // set interrupt mode and an interval (WDE must be changed from 1 to 0 here)
 watchdogRegister = bit (WDIE) | bit (WDP2) | bit (WDP1) | bit (WDP0); // set WDIE, and 2 seconds delay
 sleep_enable (); // ready to sleep
 interrupts (); // interrupts are required now
 sleep_cpu (); // sleep 
 sleep_disable (); // precaution
 } // end of goToSleep 

Compiled under the IDE it uses 16% of program memory:

Sketch uses 1,370 bytes (16%) of program storage space. Maximum is 8,192 bytes.
Global variables use 9 bytes of dynamic memory.

Claims that the Arduino IDE is badly written and inefficient are not generally true. To a certain extent the Arduino libraries favour ease-of-use over compactness, however you don't have to use them.

The IDE is just a front-end to the avr-g++ compiler. It is easy to use, and produces a .hex file which you can then upload to your chip using a suitable ICSP interface.

The avr-g++ compiler itself does aggressive code optimization. You won't get any advantage from ditching the IDE and using the avr-g++ compiler yourself - it's the same compiler. And if you think you can do better in assembler, good luck! The compiler-writers know all the tricks for storing variables in registers, and minimizing code in various ways. You will be hard pressed to write better code than the compiler generates anyway.


Claims that the IDE generates bloated code are Complete Nonsense. Take this sketch:

int main ()
 {
 DDRB = bit (2); // pin 7 on chip
 while (true)
 {
 PINB = bit (2); // blink it
 }
 }

Compiled for the ATtiny85 under the IDE 1.6.9 I get this program memory usage:

Sketch uses 60 bytes (0%) of program storage space. Maximum is 8,192 bytes.
Global variables use 0 bytes of dynamic memory.

There are 15 interrupt vectors at the start of program memory, for which space has to be reserved. So 30 of those bytes are accounted for by that unavoidable overhead.

Here is the full disassembly of the above:

Disassembly of section .text:
00000000 <__vectors>:
 0: 0e c0 rjmp .+28 ; 0x1e <__ctors_end>
 2: 15 c0 rjmp .+42 ; 0x2e <__bad_interrupt>
 4: 14 c0 rjmp .+40 ; 0x2e <__bad_interrupt>
 6: 13 c0 rjmp .+38 ; 0x2e <__bad_interrupt>
 8: 12 c0 rjmp .+36 ; 0x2e <__bad_interrupt>
 a: 11 c0 rjmp .+34 ; 0x2e <__bad_interrupt>
 c: 10 c0 rjmp .+32 ; 0x2e <__bad_interrupt>
 e: 0f c0 rjmp .+30 ; 0x2e <__bad_interrupt>
 10: 0e c0 rjmp .+28 ; 0x2e <__bad_interrupt>
 12: 0d c0 rjmp .+26 ; 0x2e <__bad_interrupt>
 14: 0c c0 rjmp .+24 ; 0x2e <__bad_interrupt>
 16: 0b c0 rjmp .+22 ; 0x2e <__bad_interrupt>
 18: 0a c0 rjmp .+20 ; 0x2e <__bad_interrupt>
 1a: 09 c0 rjmp .+18 ; 0x2e <__bad_interrupt>
 1c: 08 c0 rjmp .+16 ; 0x2e <__bad_interrupt>
0000001e <__ctors_end>:
 1e: 11 24 eor r1, r1
 20: 1f be out 0x3f, r1 ; 63
 22: cf e5 ldi r28, 0x5F ; 95
 24: d2 e0 ldi r29, 0x02 ; 2
 26: de bf out 0x3e, r29 ; 62
 28: cd bf out 0x3d, r28 ; 61
 2a: 02 d0 rcall .+4 ; 0x30 <main>
 2c: 05 c0 rjmp .+10 ; 0x38 <_exit>
0000002e <__bad_interrupt>:
 2e: e8 cf rjmp .-48 ; 0x0 <__vectors>
00000030 <main>:
 30: 84 e0 ldi r24, 0x04 ; 4
 32: 87 bb out 0x17, r24 ; 23
 34: 86 bb out 0x16, r24 ; 22
 36: fe cf rjmp .-4 ; 0x34 <main+0x4>
00000038 <_exit>:
 38: f8 94 cli
0000003a <__stop_program>:
 3a: ff cf rjmp .-2 ; 0x3a <__stop_program>

I can't see much bloat there.


I wonder if things will just be easier if I use Arduino software

Yes, much easier.

answered Apr 16, 2017 at 3:39
14
  • Although your answer is OK, I think it does not answer the main OP question: is it possible to program ATtiny85 chips on a Raspberry Pi? Commented Apr 16, 2017 at 6:48
  • Does the Pi not use Unix? The Arduino IDE runs under Unix. I run it myself under Ubuntu. Commented Apr 16, 2017 at 7:25
  • @jfpoilpret The question was actually Can I run Arduino commandline software on my Raspberry Pi? - what Arduino commandline software? Commented Apr 16, 2017 at 7:27
  • Well I would say this one: github.com/arduino/Arduino/blob/master/build/shared/… Commented Apr 16, 2017 at 7:53
  • That's because you are bypassing all of the bloat by adding your own main() function. Try doing the same with loop() instead you'll end up with 326 bytes - that's a 400% overhead on top of the simple one. But also you are using direct port access rather than digitalWrite() which is again bypassing the bloat. Try doing digitalWrite() in loop() and you'll end up with 812 bytes - a 1200% overhead! Tell me, would you consider that bloat? Commented Apr 16, 2017 at 7:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.