====== SimpleTon ======
~~META:description abstract=AVR based IO interface / automaton~~
{{tag>microcontroller sensors}}
AVR based IO interface or automaton versatile and extensible device. Up to 256 digital inputs, 256 digital outputs, 8 analog inputs and 2 analog outputs.
===== Features =====
* Cheap 8bit AVR core
* Up to 256 digital inputs (up to 32 input modules with 8 inputs per module, no IRQ)
* Up to 256 digital outputs (up to 32 output modules with 8 outputs per module)
* 8 analog inputs with 8bit resolution
* 2 analog output with 8bit resolution
* USB interface
==== About digital input modules ====
* 8 inputs
* Opto-isolator protected (0.5mA@5V - 6mA@12V current drain)
* Common ground
==== About digital output modules ====
* 8 outputs
* Open collector output modules
* 0/12V relay switched output modules
* Relay output modules
==== About analog input module ====
* 8 inputs
* 8bit resolution per input
* 0/5V or 0/10V mode by jumper setting
* Over voltage protection (zener)
* 500kΩ (0/5V) or 1MΩ (0/10V) input impedance
==== About analog output module ====
* 2 outputs
* 8 bit resolution per output
* 1 voltage output with 0/5V or 0/10V jumper-selected range and current limit safety (20mA) for each output
* 1 open drain NMOS output (9A/30V, 19mΩ) for each output
===== SimpleTon:graphlg =====
This is a grafcet-like graphical programming language for SimpleTon.
Core features :
* Up to 256 digital inputs management
* Up to 256 digital outputs management
* Up to 32 analog inputs management
* Up to 32 analog outputs management
SimpleTon:graphlg allows to define aliases for any expression, this is pretty much of a C define functionnality. Extenstion librairies can also expose their own aliases and functions.
==== Notations ====
=== IO ===
* **Ix.y** : digital input get, x is the module address (0 to 31) and y is the input channel (0 to 7), I3.2 represent the third input of the fourth module
* **Ix.y:up** : same as above but only validates if the input just had a low-to-high transition
* **Ix.y:down** : same as above but only validates if the input just had a high-to-low transition
* **Ox.y** : digital output get/set, x is the module address (0 to 31), y is the output channel (0 to 7), a value (0 or 1) can be affected
* **AIx** : analog input get, x is the input channel (0 to 31), returned result is a 0 to 255 integer
* **AOx** : analog output get/set, x is the output channel (0 to 31), a value between 0 and 255 inclusive can be affected
=== Internals ===
* **Tx** : timer get/set, x is the timer index (0 to 15)
* When used for setting given value is used as a number of timer cycles to start the timer. A typical cycle is 100ms long, this allows delays between 0.1s to nearly 110 minutes with a single timer
* When used for getting it tells if the timer has ended
* **Cx** : counter get/set, x is the counter index (0 to 15)
* When used for setting it sets the counter with the given value (0 to 65535)
* Using **Cx:up** increments the counter with the given value
* Using **Cx:down** decrements the counter with the given value
* When used for getting it tells the counter value
* **Sx** : tells if step x is active
=== Supported graphical elements ===
* Up to 32 starting steps
* Up to 1024 steps
* Source / well transitions
* Convergence and divergeance for both steps and transitions
===== Electronics =====
{{schematic>simpleton_motherboard.svg}}
{{schematic>simpleton_analog_input_module.svg}}
{{schematic>simpleton_analog_output_module.svg}}
{{schematic>simpleton_digital_input_module.svg}}
{{schematic>simpleton_digital_output_module.svg}}
{{schematic>simpleton_digital_output_with_relays_module.svg}}
{{schematic>simpleton_backbone.svg}}
===== Source code =====
// Source code
===== How to =====
===== Manual =====
===== Extensions =====
==== RGB color sensor ====
This is an inexpensive 8 colors sensor with digital and analog output.
It is based on light reflexion measurement :
* Ambient light is measured for compensation
* Target is exposed to red light
* Reflected light level is measured
* Color component is deduced from compensated measured level
* Same goes for green and blue component
* Color is calculated from components
Dedicated library for SimpleTon:graphlg.
=== Features ===
* 8 color sensing (including none)
* approx. 300ms measuring time (may be step up if light level sensing is reactive enough)
* 3 bit digital output (RGB)
* analog 0-7V output
* 12V / 30mA unregulated supply (+5V / -0.5V variation proof)
=== SimpleTon:graphlg library ===
{
"name": "Simple RGB color sensor",
"aliases": [
"COLOR_NONE": 0,
"COLOR_BLUE": 1,
"COLOR_GREEN": 2,
"COLOR_CYAN": 3,
"COLOR_RED": 4,
"COLOR_PURPLE": 5,
"COLOR_YELLOW": 6,
"COLOR_WHITE": 7
],
"functions": [
{
"name": "color",
"args": ["I", "I", "I"],
"call": "simple_rgb_sensor_digital_color"
},
{
"name": "color",
"args": ["AI"],
"call": "simple_rgb_sensor_analog_color"
}
]
}
=== Electronics ===
{{schematic>rgb_sensor.svg}}
=== Source code ===
//====================== Simple RGB sensor : main.c ========================
// MELEARD Etienne
// Year 2012
// ATMega8L @ 8MHz (internal RC oscillator)
//==========================================================================
//============================== WARNING ==================================//
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
// //
// Fuses must be like -U lfuse:w:0xc4:m -U hfuse:w:0xd1:m //
// //
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
//=========================================================================//
// ========================================= //
// == INCLUDES & MACROS == //
// ========================================= //
#include
#include
#include
#include
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
// ========================================= //
// == DEFINITIONS == //
// ========================================= //
// ================= FUSES ================= //
// Run avrdude -c usbasp -p m8 -U lfuse:w:0xc4:m -U hfuse:w:0xd1:m at first (-F may be needed)
// ================ PINOUTS ================ //
#define LED_R Bit(PORTD).bitX
#define LED_G Bit(PORTD).bitY
#define LED_B Bit(PORTD).bitZ
#define OUT_R Bit(PORTD).bit2 // MUST be continous
#define OUT_G Bit(PORTD).bit1
#define OUT_B Bit(PORTD).bit0
#define LDR_CH ADCX
// =============== CONSTANTS =============== //
#define false 0
#define true 1
#define OFF 0
#define ON 1
#define LDR_SETTIME 100 // ms
#define COLOR_NONE 0
#define COLOR_BLUE 1
#define COLOR_GREEN 2
#define COLOR_CYAN 3
#define COLOR_RED 4
#define COLOR_PURPLE 5
#define COLOR_YELLOW 6
#define COLOR_WHITE 7
// ================= INITS ================= //
void init(void) {
cli();
// Outputs
// ADC
ADCSRA = 0x80; // Manual mode, 64 prescaler (0.1ms/conv)
ADMUX = LDR_CH; // Right adjust, external ref, XX channel
sei();
}
// =============== FUNCTIONS =============== //
uint16_t getLevel(void) {
ADCSRA |= 1< b) return a;
return b;
}
// ============= MAIN FUNCTION ============= //
int16_t main(void) {
uint8_t color;
uint16_t red, green, blue, base, trig;
// Set up
init();
// Startup dance
setColor(COLOR_RED);
_delay_ms(250);
setColor(COLOR_GREEN);
_delay_ms(250);
setColor(COLOR_BLUE);
_delay_ms(250);
setColor(COLOR_NONE);
_delay_ms(250);
while(1) {
// Get no-component legel for compensation
base = getLevelForColor(COLOR_NONE);
// Get compensated components levels
red = getLevelForColor(COLOR_RED) - base;
green = getLevelForColor(COLOR_GREEN) - base;
blue = getLevelForColor(COLOR_BLUE) - base;
// Level above which component is considered as present
trig = max(max(red, green), blue) / 2;
// Compute color
color = COLOR_NONE;
if(red > trig) color += COLOR_RED;
if(green > trig) color += COLOR_GREEN;
if(blue > trig) color += COLOR_BLUE;
// Send value
PORTN &= 0xMASK;
PORTN |= color;
}
return 0;
}