Od redakce

Milí úchylové, tento web jsme letos (2026) ještě jednou (asi už popáté)  vzkřísili z nebytí.  Chtěl bych využít této příležitosti a poděkovat všem, kdo se mnou Eleferno dělali ať už autorsky, vizuálně nebo v pozadí při technické podpoře a implementaci systému.  Díky! Torm.

Prosím pozor! Tomuto textu věnujte pozornost

Eleferno je nadšenecký komunitní projekt. Nestojí za ním žádný komerční zájem ani investor, jen desítky let existence komunity, které tento web užívala jako zdroj informací, pobavení a čtení na dlouhé chvíle.

O web se po návratu z "mateřské" stará Lizz, technické zabezpečení je na web4ce, zastoupeném hlavně Sleepem. Aktuálně jedeme na sedmičkovém php a - konečně - na HTTPS a poslední pětkové Joomle, migrace na šestku ještě počká..

Uvítáme spolupracovníky - pokud byste se chtěli na Elefernu podílet technicky či autorsky, jste vítáni. Redakce má za to, že zde prezentovaný obsah zaslouží to, aby byl prezentován, ať už pro svou historickou, edukativní i prostě zábavnou hodnotu.
A slovo majitelovo:  Tento web prošel za dlouhé roky svého života složitou a členitou genezí. Od původně striktně technického a technicistního webu, specializovaného na ES, ET, vacuum a technické aspekty BDSM praxe se postupně rozrostl o zdravotnickou tématiku, otázky bezpečnosti BDSM hrátek, pubklicistiku, beletrii a nakonec i o blogy čleů redakce i vás, našich čtenářů. Dvě předchozí iterace rozvoje vnesly do orientace Eleferna prvky interaktivity a pokusily se přiblížit jej komunitnímu portálu. Z pohledu financí táhneme projekt s Nenu  a Sleepem z vlastních peněz a ano, děláme to rádi. Tato iterace vrací projekt do racionálnějších končin, diskusák ani chat opravdu neplánujeme :) Všichni jste ovšem upřímně vítáni. Takže - HAPPY ELECTRODES!

První nový Elesraz NG proběhne 7.10.2026 (a následně každou první středu v měsíci) v Ateliéru souběžně s tradiční nekonvenční saunou (není povinná, jde jen o organizační souběh). 
Předpokládá podobný formát, jaký elesrazy mívaly, ovšem se zohledněním faktu, že píšeme rok 2026. Jako primární prostor jsme zvolili strašnický Ateliér, pokud se akce rozběhnou, projednáme i variantu sekundárního (a komornějšího) prostoru u Maxe. Co takový sraz obnáší - především možnost potkat se s podobně naladěnými lidmi, něco nového se naučit, vyzkoušet, případně si i zaakčnit s půjčenou nebo i vlastní technikou, klidně i s odborným dohledem. V případě zájmu bude i možno nechat si změřit vlastní hračky nebo i prokonzultovat vaši vlastní konstrukci. Sraz je ale primárně akční. Pokud by se nahromadily požadavky na nějaký edukativní formát, zohledníme jej při plánování.

 

Popisovaný nápad pochází z KinkLabu a ukazuje, jak snadno a levně lze s pomocí moderních technologií jednočipů řešit i poměrně složitá technická zadání. 

Popisované zařízení slouží jako externí box pro připojení prakticky libovolné vibrační jednotky s napájecím napětím v rozmezí od 6 do cca 18V, alespoň principiálně řiditelné pulsně šířkovou modulací. S firmwarem, ocitovaným níže hračka umožňuje připojení k PC via USB a programové řízení nadřízeným počítačem (včetně nahrávání až pěti vlastních průběhů do EEPROM Arduina), program řízení rychlosti vibrace, řízení náběhových obálek a program rozmítání rychlosti mezi nastavenými hodnotami plus pět již zmíněných vlastních průběhů. Text není podrobným návodem ke stavbě, pojednán je spíše inspirativně :-)

Ke stavbě je zapotřebí - kromě vývojového kitu Arduino - už jen pár šuplíkových součástek. Konkrétně dva lineární potenciometry 10 kiloohm, přepínač 1x9, osm odporů po jednom kile, jeden zhruba desetiohmový odpor, výkonový N-MOSFET podle výkonu poháněného vibrátoru a Schottkyho diodu na ochranu tranzistoru před špičkami z motorku hračky. Celé schéma pak vypadá takto:

Ano, přepínač je opravdu vyřešen digitalizací napětí z odporového děliče. Zbývá firmware:

#include <EEPROM.h>
#include <Messenger.h>
/* VIBROCONTROLLER  v0.1
by elims - Tato e-mailová adresa je chráněna před spamboty. Pro její zobrazení musíte mít povolen Javascript. 
Mode 0: PC-Mode
Mode 1: const
Mode 2: ramp
Mode 3: fade
Mode 4 - 8: Read wavetable from EEPROM
*/
// ### globals ####################################################
Messenger message = Messenger();         //Instantiate the remote access
int pwmpin = 6;                           // PWM for vibrator
int indloadpin = 5;                       // Inductive load
int modepin = 0;                          // Resistor kaskade (7x 1k) for mode selection
int powerpin = 1;                         // 10k variable resistor for power
int freqpin = 2;                          // 10k variable resistor for time
int value = 0;                            // temporal value
int address = 0;                          // global iterator
int modevalue = 0;                        //
float strength = 0;                       // variable to keep the actual PWM value (0-255)
boolean rampup = true;                    // goes ramp up or down in
byte mode = 0;                            // Stores the current Mode
// ### functions ###################################################
void fade(){
strength = float(analogRead(powerpin))/1024.0;
if(value >= 255){
rampup = false;
}
if(value <= 0){
rampup = true;
}
if(rampup==true){
value += 5;
} else {
value -= 5;
}
analogWrite(pwmpin, int(float(value)*strength));          
delay(analogRead(freqpin)/2+5);                            
}
void ramp(){
strength = float(analogRead(powerpin))/1024.0;
if(value >= 255){
value = 0;
} else {
value += 5;
}
analogWrite(pwmpin, int(float(value)*strength));          
delay(analogRead(freqpin)/2+5);
}
/* inverse ramp
void iramp(){
strength = float(analogRead(powerpin))/1024.0;
if(value <= 0){
value = 255;
} else {
value -= 5;
}
analogWrite(pwmpin, int(float(value)*strength));          
delay(analogRead(freqpin)/2+5);
}
*/
void tablelookup(int table){
strength = float(analogRead(powerpin))/1024.0;
value = EEPROM.read(address + table*100);
if(address >= 99){
address = 0;
} else {
address += 1;
}
analogWrite(pwmpin, int(float(value)*strength));          
delay(analogRead(freqpin)/2+5);
}
// Create the callback function
void messageReady() {
if (message.available()) { // Checks to see if the message is complete and erases any previous messages
if (mode > 0) {
Serial.print('i');
Serial.print(' ');
Serial.print(mode, DEC);
Serial.println();
} else {
switch (message.readChar()) { // Gets the first word as a character
case 'r': // Read pins (analog or digital)
readeeprom(); // Call the readpins function
break; // Break from the switch
case 'w': // Write pin
writeeeprom(); // Call the writepin function
break;
case 's':
setoutput();
break;
case 'i':
Serial.print('i');
Serial.print(' ');
Serial.print(mode, DEC);
Serial.println();
}
}
}
}
void readeeprom() { // Read pins (analog or digital)
int table = 0;
int add = 0;
switch (message.readChar()) { // Gets the next word as a character
case 'e':
Serial.print('e');
Serial.print(' ');
add = message.readInt();
Serial.print(add);
Serial.print(' ');
Serial.print(EEPROM.read(address), DEC);
break;
case 'p':
Serial.print('p');
Serial.print(' ');
table = message.readInt();
Serial.print(table);
Serial.print(' ');
for(int i = 0; i < 100; i++) {
Serial.print(EEPROM.read(i + table*100), DEC);
Serial.print(' ');
}      
break;
case 'a': // READ analog pins
Serial.print('a');  // Echo what is being read
Serial.print(' ');
Serial.print(analogRead(powerpin));
Serial.print(' ');
Serial.print(analogRead(freqpin));
Serial.print(' ');
}
Serial.println();
}
void writeeeprom() { // Write pin
int table = 0;
int batch = 0; //multipurpose integer (adresse, batchadresse, formatvalue)
switch (message.readChar()) { // Gets the next word as a character
case 'e' :
batch = message.readInt();
EEPROM.write(batch, message.readInt());
Serial.println('d');
break;    
case 'p':
table = message.readInt();
batch = message.readInt();
for(byte i = 0; i < 10; i++) {
EEPROM.write(i + batch * 10 + table*100, message.readInt());
}
Serial.println('d');
break;
case 'f':
table = message.readInt();
batch = message.readInt();
for(byte i = 0; i < 100; i++) {
EEPROM.write(i + table*100, batch);
}
Serial.println('d');
}
}
void setoutput() {
switch (message.readChar()) {
case 'a' :
analogWrite(pwmpin, message.readInt()); //Sets the PWM of the pwmpin
break;  // Break from the switch
case 'b' :
analogWrite(indloadpin, message.readInt());   //Sets the PWM of the indloadpin
}
}
// ### main ###########################################
void setup()
{
Serial.begin(9600); // 115200
message.attach(messageReady);
pinMode(pwmpin, OUTPUT);
pinMode(indloadpin, OUTPUT);
} 
void loop()
{
while (Serial.available())  message.process(Serial.read());
modevalue = analogRead(modepin)/4;
if(modevalue >= 0 && modevalue < 16) {
value = 0;  //make sure ramp and fade start with 0
mode = 0;
}
if(modevalue >= 16 && modevalue < 48) {
analogWrite(pwmpin, analogRead(powerpin)/4);
mode = 1;
}
if(modevalue >= 48 && modevalue < 80) {
mode = 2;
ramp();
}
if(modevalue >= 80 && modevalue < 112) {
mode = 3;
fade();
}
if(modevalue >= 112 && modevalue < 144) {
mode = 4;
tablelookup(0);
}
if(modevalue >= 144 && modevalue < 176) {
mode = 5;
tablelookup(1);
}
if(modevalue >= 176 && modevalue < 208) {
mode = 6;
tablelookup(2);
}
if(modevalue >= 208 && modevalue < 240) {
mode = 7;
tablelookup(3);
}
if(modevalue >= 240 && modevalue < 257) {
mode = 8;
tablelookup(4);
}
}