聊聊垃圾贴 & 净化CN区行动

从我之前的几篇帖子以及社区上其它帖子中,想必大家时常听到两个ID:
cheetah 以及steemcleaners (不加@ 以免不小心召唤来)
这篇文章我们来随便聊聊垃圾帖,希望能对净化中文社区起到些许作用。

执法机器人以及志愿者

cheetah

cheetah是一个机器人,运作的机制是新帖子发表以后,它去网上比对是否有雷同内容,一旦发现雷同,则将雷同内容的链接回复到对应帖子底下,供其它点赞者判断和参考。

cheetah并不直接差评帖子,所以一旦它判断出错,并不会直接影响帖子的收益。
如果你的帖子被cheetah误判,可以直接给它回复,陈述一下属于误判,基本没啥大影响。

cheetah 由 @anyx 创建和维护。

steemcleaners

steemcleaners是一队志愿者,掌握着一些大鲸鱼账户的点赞权(差评权),这些志愿者每日浏览成千上万的帖子,从中发现抄袭贴身份伪冒骗子垃圾帖等内容,并进行响应的处理(差评,通知其它已点赞的大鲸鱼取消投票等)。藉此维护steemit站点上的清洁,而不是被垃圾和骗子充斥。

其它志愿者

社区还有一些其它团队和志愿者也在做类似的事情,但是因为我对这方面了解不深,所以很难一一罗列,在此对所有维护steemit站点清洁的朋友表示敬意和谢意。

何为垃圾帖?

通过对上述机器人和志愿者的介绍,大家可以看出,无论是机器人还是志愿者对垃圾帖的判断都很严格。与宁可错杀一千,不可放过一人相反,几乎是秉承绝不错杀一个的原则。那么问题来了,什么样的帖或者说ID是要被重点打击的呢?

1) 抄袭/盗用、
完全复制他人或者其它网站内容的文章,冒充是自己创作,发表到steemit上来。
CN区上我见过几个ID,直接克隆CN其它作者的作品,以至于我一度怀疑眼睛花了,仔细审核后,当然毫不留情的处理。

2) 身份伪冒
这个较难发现,仿冒者去fb、instagram等站点找个用户,然后把对应用户的照片帖子搬到steemit上来,或者更进一步,把对应的英文帖子人工或者google等工具翻译成中文帖子,识别难度更是倍增。尤其是仿冒者随时关注被仿冒者的更新,并及时同步到steemit上来,让人看起来像其本人一样。前两天看到中文区一个带女孩照片的自我介绍,而且自称是从小生活在中国的,其中帖子的中文部分,估计无人能读懂,我还回帖质疑一下呢,结果没过多久就被举报是盗用别人照片,然后被执法大队踩死了。

3) 骗子/钓鱼
骗子比较好理解了,发个钓鱼网站让大家访问,或者发布点啥虚假信息号召大家支持和捐款等等,无非是各种流行骗术搬到steemit上来。大家擦亮眼睛,不要上当。

4) 其它垃圾帖
除了以上三种严重的垃圾帖子以外,还有诸如将中文用机器翻译成英文/英文翻译成中文,或者使用大量无关内容在某个类目下SPAM,或者宣扬种族歧视以及恐怖主义等等

区分垃圾贴和低质量帖子

steemit是个开放的社区,尽管会从获取收益、提高声望等角度奖励并促进作者创作出优质内容,但是发出诸如今天天气真好啊今天晚饭我吃的好饱这些内容也是被允许的,并非属于垃圾内容。

大家有把steemit当成个人博客随便放些心情日志之类的内容的权利
当然,能收获多少点赞,以及获得多少奖励,就看你的人气了。
但是如果用大量的类似内容(比如说一天20条以上)充斥某一类目,影响了大家对正常内容的阅读,就会被认作是SPAM了。

关于错误的使用CN Tag

我们常来CN区的朋友知道,CN tag代表的是中文社区。而一些外国人可能出于蹭热门tag的缘故,在帖子中使用CN TAG, 对此我们要区别对待。如果内容属实和中文区有关或者和中国有关,又不属于上述垃圾帖的范畴,尽管可能不含中文,但是对于质量上乘的我们依旧表示欢迎。如果完全与CN或者中文无关并且质量低劣,我们可以告知他们CN tag的使用规则,并建议其移除帖子的cn tag。总之,以劝导为主,雷霆打击仅适合上述严重垃圾帖

中文社区垃圾帖的识别的难度

由于语言的差异,老外的志愿者团队可能很难识别出中文社区的垃圾帖。
举例说我发一个: 透露六合彩特码的群推广,收取会员费,骗人加入的帖子
老外们很难通过技术手段分析出来这是个骗人的帖子,属于需要清理的范畴。
所以中文社区的垃圾帖需要更多的中文社区朋友协同作业,才可能让坏人、坏贴无处遁形。

以上是个人见解,可能有失偏颇,供大家参考和讨论。
欢迎大家回复宝贵意见和建议


净化CN区行动


欢迎大家在本贴回复符合上述垃圾帖定义的中文区内帖子, 并提供相应的证据

比如,

1
2
3
帖子: https://steemit.com/@xxxxxxx/xxxxxx
原因:完全复制网上帖子
原文地址: http://www.baidu.com/xxxxx

一经核实,我们会给予对应的处理,谢谢大家。
CN社区是大家共同家园,让我们一起爱护她维护她。


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: 聊聊垃圾贴 & 净化CN区行动

聊聊点赞机器人的点赞策略 /The Policies of Curation Bots

在前文:

我们粗略的谈及了点赞机器人/Curation Bots, 这里我们来聊聊点赞机器人的策略。

策略/Policies

无论是出于支持指定作者还是攫取点赞收益,点赞机器人都不能瞎点乱点。
那么点谁的帖子、何时点、点多少比例就是点赞机器人需要解决的问题,在这里,我将这些笼统的概况为策略/Policies。
大致可以归结为以下几点:

  • 点谁 / Who
  • 何时点 / When
  • 点多少/ How much

点谁 / Who

关于点谁的帖子,一般有以下策略:

  • 逮谁点谁 / Upvote every post

逮谁点谁的主要目的就是混脸熟,当然也可能是为了支持所有人

下表为SteemIT 创立以来点赞最多的三个ID
Rank. |ID |Votes |SP |VP(%) |Rep |Online
—-|—-|—-|—-|—-|—-|—-
1 |@fyrstikken|215493|491880.04|56.58|72.84|362
2 |@sqube|129641|12281.60|98.00|38.65 |256
3 |@ubg |103831|3241.64|0.97|57.89 |351

我没去统计现在STEEMIT一共多少文章正文了,但是我知道fyrstikken的机器人开动的时候,是逢帖必点的。有些新作者,零人气,突然有个大户给点了一票,尽管可能给的权重是1%或者0.01%,但是依旧足以让人欣喜若狂了。可惜的是fyrstikken时不时的停机,尤其HF19之后,可能不再按之前的策略开动了,所以新人们享受不到这项福利了。

而ubg,大家注意一下这个哥们的VP,已经低至0.97%,也就是说他100%的一票,相当于满权重时的1%,而1%的一票则相当于万分之一了。

由此可见,逮谁点谁,这种策略不可取,HF19之后,更是行不通了。

  • 跟谁指定的作者 / Upvote the specified authors

这是另外一种简单的策略,也是应用最广的策略。
1)某些作者一向收益奇高,点他可以获得巨额回报
2)某些作者是我们的好友或者值得支持,文章质量非常好,值得逢帖必点

操作起来也很简单,机器人监控steemit上的新帖,发现有这些作者的帖子,就加入处理列表,什么时候点,点多少就是另外的话题了。

  • 跟随指定的操作者 / Follow the specified curator

这个策略白话描述就是别人点谁我点谁。
@wang 作为全网知名的点赞机器人,有段时间监控 @deanliu 的操作,只要@deanliu 点的帖子,他就必点,@deanliu 为此兴奋过好长一段时间😀

这个策略相当于一个领头人,领头人的操作被大家所认同,curie 等一些点赞机器军团之前也是这样的策略。
这个策略有一个弊端,可能存在几伙机器人,而几伙机器人中的几个号码可能互相跟点,然后就串号了,几波大军跟点一个帖子,对帖子主人来讲,当然是极好的啦,尤其HF19之前,收益倍增啊

  • 动态分析 / Analysis Dynamically

这种形式相对复杂,通过作者(信用、发帖频度、SP等等)以及文章(标签、长度、图片、内容等等)以及其它点赞者对帖子的行为(点赞、差评、回复等等)来动态分析这个作者的帖子是否可以点。这个模式相对复杂,但是会筛选出相对比较优秀的帖子。

  • 组合策略 / Combined The Policies

组合策略很好理解,就是综合以上几种策略中的两种或者N种,所形成的点赞策略,不用过多描述啦。

何时点 / When

确定了点谁、点哪个帖子之后,就是何时点的问题,关于这个问题主要涉及两个方面:

  • 早鸟惩罚
  • 迟到者抬轿

所谓早鸟惩罚,就是为了避免机器人抢投所有的帖子,限定了30分钟以内点贴,点赞收益与作者按比例分成。而所谓迟到者抬轿,就是先点的比后点的分得更多的点赞收益。所以对于机器人点赞而言,点早了不合算,点晚了也不合算,而正好30分钟点,对不起,很多人在20分钟时候就开始抢投了。具体什么时间合适,可能需要经过精细的计算以及对帖子当前的收益状态进行分析,并对其它大鲸鱼是否跟点这一作者、什么时机点这一作者进行针对性对待,这个工作量可谓大矣。

点多少/ How much

大家可能注意到一些机器人号对不同作者不同帖子点赞时给予了不用的权重,有的1%,有的100%

当解决了点谁以及何时点之后,点多少比重这个事情其实就很简单了,无外乎一下几点:

  • 这个作者平时的文章质量如何: 是否值得全力支持
  • 点这个帖子会获得多少收益: 潜在收益越高,比重越大
  • 当前的Voting Power 情况: VP低的时候降低比重可以保持VP回复较快(或下降较慢)

如何被机器人爱上

通过上述分析,我们会发现机器人的策略有的简单、有的复杂,那么对于普通作者而言,如何让机器人爱上呢?这个问题其实不太好回答,但是我尝试给出以下结论:

  • 声望(Reputation): 信用几乎是大部分机器人策略考察的重点,信用越高,被盯上的可能性越大
  • 金钱(Money): 你拥有的等效SP(SP+代理)决定了你点贴收益,也是机器人们判断你的帖子潜在收益的重要依据
  • 质量(Quality): 声望和金钱,一时半会解决不了,但是如果质量不高,那么就更无望了
  • 人际交往(Relationship): 和每个人交朋友,让更多的人看到你的帖子,如果遇到伯乐,你还是千里马,那么你就有可能被加入名单了

其中声望和金钱要一时半会解决不了,就只能从质量和交往两方面着手了。有句话叫做: 是金子总会花光的发光的,保持高质量水准,万一被curie啥的发现了呢!至于人际交往,切记要真心和人做朋友,如果你交朋友的目的就是让人家给你点赞,那么相比朋友和点赞你都收获不到。

以上是随便聊聊机器人的点赞策略,个人见解,不可能面面俱到,也可能有失偏颇。
欢迎讨论,欢迎指正。


感谢阅读 / Thank you for reading.
欢迎upvote、resteem以及 following me @oflyhigh 😎


This page is synchronized from the post: 聊聊点赞机器人的点赞策略 /The Policies of Curation Bots

Arduino 开发不传之秘: 使用ATMEL328P Timer1 FAST PWM 直接控制伺服电机(Servo motor)

需求

想必接触过物联网(IOT)的兄弟姐妹们对Arduino不会陌生,没错,在ESP8266横空出世之前,Arduino Uno R3是当之无愧的最流行的物联网原型搭建平台,也是被使用最广的教学平台。回想起去年7月份的时候,我还写过两篇和Arduino有关的文章,大致是用Arduino计算我的个人资产何时能够超过DAN,现在看来,这想法真好笑;)

这篇文章介绍Arduino的高级技巧,其实呢,Arduino最大的便利就在于模块化以及对底层库的封装,用户无需了解过多的技术细节就能迅速的搭建出好玩的或者实用的应用。但是总有一些复杂的情况,这时候你若对底层一点不了解,就会比较抓瞎了。

比如说:前阶段一个朋友丢给我一个需求,截图如下:
homework.jpg

大致就是让用AVR Clib的方式实现用ATMEL328P Timer1 的FAST PWM 直接控制伺服电机。简单的说,就是不允许使用库,而是要了解相关的技术细节,直接实现。

需求的细化

对上述需求进行了一下细化:

  • 1:实现Timer/counter 1 生成 fast PWM 信号
  • 2:实现用PWM信号去控制Servo motor
  • 3:实现用两个按键分别控制Servo motor正转反转,每次旋转30度
  • 4:实现EEPROM的读写
  • 5:存储当前Servo motor位置,实现Arduino重启等自动复位

分别对其进行详细的分析

1:Timer/counter 1 生成 fast PWM 信号

为了实现Timer1生成 fast PWM信号,我们查找了Atmel的芯片手册(328P).
Timer1是16位定时器,有很多种工作方式,我们选取的fast PWM方式
工作方式的选择是通过:Waveform Generation Mode 进行选择的

Waveform Generation Mode
我们选择模式14:1 1 1 0
(Page 134 of atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet.pdf)

Compare Output Mode, Fast PWM
Set OC1A/OC1B on Compare Match, clear OC1A/OC1B at BOTTOM (inverting mode)

ICR1作为比较的最大值,我们令其为40000 - 1
OCR1A 控制脉宽(占空比等)

分频选择 8分频, CS11

按如上设置,我们生成50HZ的PWM信号
频率公式:频率 = 时钟周期/分频/(最大值+1)

(* 关于数值的选取:分频,以及最大值等,是由电机脉宽计算出来的)

2:实现用PWM信号去控制Servo motor

查找一些技术文档后,发现控制Servo motor的不是PWM的占空比,而是脉冲信号中高电平持续的时间。
http://en.wikipedia.org/wiki/Servo_control

这个时间对应不同的电机,一般对应0.5毫秒-2.5毫秒,与0-180度对应。
为了实现更高精度的控制,我们将其扩大1000倍,亦即我们可以操作的最小时间是0.5/1000 = 0.0005

而对应到计数值,则为1000(0.5/ 0.0005) 与 5000 (2.5/ 0.0005)
通过最小时间,我们可以反推出分频的选择(8分频)
通过计数值以及占空比(2.5%,12.5%)以及频率,我们选择40000作为最大值。

所以,我们讲0-180,映射至1000-5000,通过修改OCR1A的值,就可以控制高电平持续的时间,进而控制电机。

由于以上两部分是紧密关联的,所以我们实现了一个函数:
void PWM_Servo_Move(int angle), 输入角度,实现对应旋转(0-180度)

3:实现用两个按键分别控制Servo motor正转反转,每次旋转30度

我们设计了一个函数:
boolean bButtonPressed(int nButton, int & pre_sta)
输入按键针脚,以及之前的状态,来判断是否被按下(我们判断KEYDOWN)

(这个函数可以进一步把pre_sta做到里边)

我们用一个全局变量计数器CUR_POS(0-6)来记录按键
进行对应的操作
舵机旋转CUR_POS * 30

4:实现EEPROM的读写

对于EEPROM,Arduino以及Avr都有完善的库支持
(Arduino库封装了Avr的库)

为了实现脱离库函数对EEPROM读写
我们查找了ATMEL的手册,doc8161.pdf
从中找到对寄存器直接操作的代码,实现了特定型号MPU EEPROM的读写

5:存储当前Servo motor位置,实现Arduino重启等自动复位

为此我们定义了

1
2
3
4
5
6
7
struct MY_SETTING
{
byte header[6];
unsigned int W_CNT;
unsigned int R_CNT;
byte CUR_POS;
};

并实现
void Load_Setting() // 在程序启动时,加载设置
void Save_Setting() //在用户按键时,保存设置

问题解答

  • 1:测量并汇报EEPROM读写次数(读写时间)?是否满足需求?
    因为叫不准要的是读写次数,还是时间,Times, 原谅我的烂外语,我就都加了
    读写次数也记录并汇报,操作时间也汇报
    (Load Setting 20微秒,Save Setting 34448 微秒,34毫秒,对程序没有影响)

  • 2:首次加载程序时,EEPROM内容未知,处理这种情况
    我们定义了一串字符头,作为EEPROM已经初始化的标志。
    如果与标志不符,我们就初始化EEPROM

  • 3:如果每天用户按键100次,那么程序(EEPROM处理)能按预期运行多久?
    手册上说:
    An EEPROM write takes 3.3 ms to complete. The EEPROM memory has a specified life of 100,000 write/erase cycles, so you may need to be careful about how often you write to it.
    那么每天100,可以工作1000天。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#define BUTTON_ADD     2
#define BUTTON_SUB 4
// Can’t be changed, because we use OCR1A
#define SERVO_PIN 9

// Function declaration
void PWM_Servo_Move(int angle);
void EEPROM_write(unsigned int uiAddress, unsigned char ucData);
unsigned char EEPROM_read(unsigned int uiAddress);
boolean bButtonPressed(int nButton, int & pre_sta);

// Globe variables
int BA_PRE = LOW; //previous status for BUTTON_ADD
int BS_PRE = LOW; //previous status for BUTTON_SUB
int CUR_POS = 0; // Save the current Position (Angle = CUR_POS * 30)

void setup()
{
pinMode(SERVO_PIN , OUTPUT);
pinMode(BUTTON_ADD, INPUT);
pinMode(BUTTON_SUB, INPUT);

Serial.begin(9600);

// Load setting since last start and Move servo
Load_Setting();
PWM_Servo_Move(CUR_POS*30);
}

void loop()
{
if (bButtonPressed(BUTTON_ADD, BA_PRE))
{
CUR_POS = (CUR_POS == 6) ? 6: ++CUR_POS;
Serial.print("BUTION_ADD Pressed! Position is: "); Serial.println(CUR_POS);
Save_Setting();
}

if (bButtonPressed(BUTTON_SUB, BS_PRE))
{
CUR_POS = (CUR_POS == 0) ? 0: --CUR_POS;
Serial.print("BUTION_SUB Pressed! Position is: "); Serial.println(CUR_POS);
Save_Setting();
}

PWM_Servo_Move(CUR_POS*30);
}



/**********************************************************************************/
/************************ Functions for Button ************************/
/************************ Return true when Key down ************************/
/**********************************************************************************/
boolean bButtonPressed(int nButton, int & pre_sta)
{

int btn_sta = digitalRead(nButton);

// Keydown
if (btn_sta != pre_sta && btn_sta == HIGH ) {
delay(20);
pre_sta = btn_sta;
return true;
}
// KeyUP
else if (btn_sta != pre_sta && btn_sta == LOW )
{
delay(20);
pre_sta = btn_sta;
}

return false;
}

/**********************************************************************************/
/************************ Function for Settings ************************/
/************************ Read or Write Setting via EEPROM ************************/
/**********************************************************************************/
struct MY_SETTING
{
byte header[6];
unsigned int W_CNT;
unsigned int R_CNT;
byte CUR_POS;
};
struct MY_SETTING G_Setting;
const char EP_HEADER[6] = {'I', 'N', 'I', 'T', 0, 0};

// Load Setting from EEPROM
void Load_Setting()
{
boolean bInit = true;

// Read setting from EEPROM
byte * p = (byte *)&G_Setting;
unsigned long time = micros();
for(int i =0; i<sizeof(struct MY_SETTING); i++)
{
p[i] = EEPROM_read(i);
}
time = micros() - time;

// Check if EEPROM was initialized
for(int i=0; i< sizeof(G_Setting.header); i++)
{
if(G_Setting.header[i]!= EP_HEADER[i])
{
bInit = false;
}
}

// Initialize it if necessary
if(!bInit)
{
Serial.print("Not initialized, Initialing.....");

// Write the initial setting to EEPROM
for(int i=0 ; i<sizeof(EP_HEADER); i++)
{
G_Setting.header[i] = EP_HEADER[i];
}
G_Setting.W_CNT = 0;
G_Setting.R_CNT = 0; //0xabcd for test
G_Setting.CUR_POS = 0;
for(int i =0; i<sizeof(struct MY_SETTING); i++)
{
EEPROM_write(i, p[i]);
//delay(10);
//Serial.print(i); Serial.print("= "); Serial.println( p[i]);
}
Serial.println("Done!");
}

// Increase the read counter
G_Setting.R_CNT++;

// Report setting info
Serial.print("Write counter: "); Serial.println( G_Setting.W_CNT);
Serial.print("Read counter: "); Serial.println( G_Setting.R_CNT);
Serial.print("Current Positon: "); Serial.print( G_Setting.CUR_POS); Serial.print("\tAngle: "); Serial.println(G_Setting.CUR_POS * 30);
Serial.print("Seting Loaded: Time cost: "); Serial.print(time); Serial.println(" microseconds");

// update position
CUR_POS = G_Setting.CUR_POS;
}

void Save_Setting()
{
byte * p = (byte *)&G_Setting;

// Increase the write counter and update the current position
G_Setting.W_CNT++;
G_Setting.CUR_POS = CUR_POS;

// Write setting to EEPROM
unsigned long time = micros();
for(int i =0; i<sizeof(struct MY_SETTING); i++)
{
EEPROM_write(i, p[i]);
//delay(10);
//Serial.print(i); Serial.print("= "); Serial.println( p[i]);
}
time = micros() - time;

// Report setting info
Serial.print("Write counter: "); Serial.println( G_Setting.W_CNT);
Serial.print("Read counter: "); Serial.println( G_Setting.R_CNT);
Serial.print("Current Positon: "); Serial.print( G_Setting.CUR_POS); Serial.print("\tAngle: "); Serial.println(G_Setting.CUR_POS * 30);
Serial.print("Seting Saved: Time cost: "); Serial.print(time); Serial.println(" microseconds");
}


/**********************************************************************************/
/************************ Function for Servo ************************/
/************************ Use timer/counter1 ************************/
/**********************************************************************************/
#define MIN_PULSE_WIDTH 0.544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2.4 // the longest pulse sent to a servo
#define STEP_WIDTH 0.0005 // (*) Calculated Value, can't be changed

void PWM_Servo_Move(int angle)
{
if (angle > 180)
angle = 180;

if (angle < 0)
angle = 0;

// Disable interrupts
cli();

//
// 16.11.1 TCCR1A – Timer/Counter1 Control Register A
// COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
// WGM = 1110 : Fast PWM, TOP = ICR1 (page134)
// Clock Select Bit Description = B010: clkI/O/8 (From prescaler) (page135)
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11) ;
//TCNT1 = 0; // clear the timer count

// Set the value of TOP, which generate 50HZ frequency (20ms per cycle)
ICR1 = 40000 - 1;

// Map the angle value to counter, then set counter, begin count
unsigned int counter = map(angle, 0, 180, MIN_PULSE_WIDTH/0.0005, MAX_PULSE_WIDTH/0.0005);
OCR1A = counter;

// Re-enable interrupts
sei() ;
}

/**********************************************************************************/
/************************ Function for EEPROM ************************/
/************************ Copy from Atmel ************************/
/**********************************************************************************/
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEPE));
/* Set up address and Data Registers */
EEAR = uiAddress;
EEDR = ucData;
/* Write logical one to EEMPE */
EECR |= (1<<EEMPE);
/* Start eeprom write by setting EEPE */
EECR |= (1<<EEPE);
}

unsigned char EEPROM_read(unsigned int uiAddress)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEPE));
/* Set up address register */
EEAR = uiAddress;
/* Start eeprom read by writing EERE */
EECR |= (1<<EERE);
/* Return data from Data Register */
return EEDR;
}

连线图

IMG_4024.JPG

就这样啦,不传之秘哦!


This page is synchronized from the post: Arduino 开发不传之秘: 使用ATMEL328P Timer1 FAST PWM 直接控制伺服电机(Servo motor)

聊聊机器人🤖 / Robots on STEEMIT

昨天被一个欢迎机器人引发一堆感慨:

今天就来和大家聊聊机器人。
Today, Let’s talking about robots on steemit.

高大上的机器人 / Robots in life

也许很多朋友看过波士顿动力(Boston Dynamics)的各种机器人视频,被各种屌炸天的机器人所震惊,什么Handle啊、Spot、Atlas绝对挑战你之前的认知,或许真的用不了多少年,变形金刚里的场景会变成我们生活中的现实。

也许很多朋友阿尔法狗(AlphaGo),是一个在某些方面比人类更聪明的狗,哦不对,是机器人,是一款利用深度学习原理的围棋人工智能程序,总之,无数大师级人物折戟沉沙。OMG,是不是机器人统治人类的时候即将到来?

还有不少工业机器人,其实与其说机器人,不如说是机械臂,或者一堆执行器,智能程度堪忧,只是按指令行事。不过即便如此,工业机器人+ 制造执行系统 (manufacturing execution system, 简称MES)代替的大量的繁重人工工作,而且会愈演愈厉,到底是解放了人类还是导致大量的失业?这个就不是我所能理解和评论的范畴了。

至于餐馆的送餐机器人、银行柜台的迎宾机器人,更是弱到爆了,送餐机器人,本质就是一个巡线小车的放大版。什么?你没听说过巡线小车,也难怪,这些东西是现在小学生玩的玩意,几千块钱的乐高加上三两天培训,轻松搭建出来。你说哎,堆积木嘛,技术含量都在积木本身里呢。其实技术含量也不高,其实就是一组红外传感器,照到线上和不在线上返回不同信号,然后,你懂的。迎宾机器人,你可能在电视节目中看过她们高大上的表演,其实不过是一个喇叭,加上WIFI通信,然后真人猫在后边控制室,与你对话。不信?这是事实!

STEEMIT 相关机器人 / Robots on STEEMIT


擦,又扯远了,其实我想聊的主题是steemit上的相关机器人。

  • 🤖机器人种类之一: 欢迎机器人 / Welcome Bots

欢迎机器人是steemit上最早出现的STEEMIT机器人种类之一,其始祖可以追溯到 @wang , wang 这个名字不错,充满王霸之气。每当steemit 新人上来发自我介绍,王就回复一篇入门指南,帮助了无数新人。然后,有一天,领导们说王这么干不好,咱们踩死他吧,可怜的王被活生生的踩死了,信用分(-16) 我没有统计过是不是全网最低,但也八九不离十啦。最近欢迎机器人又开始流行起来,除了我上文提到的转钱机器人,让你苟富贵,勿相忘的,还有一个welcomebot,做着和wang 一摸一样的事情。领导们或许没发现、或许不屑搭理、或者忙着做其它重要的事情、或者心情彼一时此一时?总之,领导的心思你别猜。

  • 🤖机器人种类之二:点赞机器人 / Curation Bots

欢迎机器人的策略是混个脸熟,然后收获一些粉丝啥的,或者弄一些号码点赞自己的欢迎语,弄点收益。说到点赞,就不得不提点赞机器人了。点赞机器人通过发现和点赞热门帖子,赚取点赞收益。HF19之前,点赞集中的特别明显,因为计算合理的话,点热门帖子赚钱更多。所以造成了热门帖子越来越热,冷门帖子无人问津的状况。HF19之后,因为文章收益改为线性回报曲线,扎堆点的状况略有改善,都变成自己给自己点了,所以点赞机器人依旧大有用武之地。另外,还有一些原因,比如说你认为有些作者的帖子你必须要支持的,但是不能时刻盯着点啊,所以加入某一点赞大军,也未尝不是一个选择。还有诸如chainbb、esteem等等,开发者们一方面测试应用、一方面赚取点赞收益、一方面赚取作者收益的分成,这时候如果人工点,不用点赞机器人,那么开发者们不用做其它事情了。总之,各种原因,点赞机器人依然是steemit全网应用最广的机器人了。

  • 🤖机器人种类之三:发帖机器人 / Posting Bots

Steemit 发帖可以赚钱,这个可能是吸引很多用户过来的主要原因。硬叉19之前因为收益较少所以比较冷清,而19之后,因为收益增加,老人们纷纷回归,新人纷至沓来,赚钱效应可见一斑。既然发帖可以赚钱,那么就有人想到用机器人发帖,自己收钱,岂不是爽哉?思路没错,如若机器人能写出优质文章,那么赚钱似乎也不是很难的事情。问题就在于,机器人没有自己的思想,写出的文章往往四不像,或者当个搬运工,从其它网站搬内容至STEEMIT,然后,嗯,执法机器人还是相对公正的。更有甚者,我看到过把STEEMIT当矿场的,一个机器人发一句话,然后数千个点赞机器人点上去,没错是数千个,然后被大鲸鱼们发现了,活活踩死。发帖机器人,若能找到大家都感兴趣的话题或者功能,赚点小钱还是有可能的,但是HF19之后,大家都开始珍惜自己的权重了,所以想赚钱得先有钱,然后钱生钱。赤裸裸的金钱法则。

  • 🤖机器人种类之四:执法机器人 / Police bots

Steemit 作为社区有些像一个小小的社会,既然是社会,就有三六九等之人。俗话说,林子大了,什么鸟都有,一两只坏鸟到处扰乱林子治安,这时候一些志愿者就站了出来,说我们要维护社区环境,让公平正义得到伸张。然后一堆执法机器人就诞生了,代表有Cheetah、steemcleaners等。执法机器人属实在维护社区治安上起到不小的作用,让一些抄袭、剽窃者的内容无所遁形,或者通过黑名单机制将一些作恶号码踩死。但是执法过程有时候难免粗暴。我之前有的帖子明明是自己辛苦创作的,代码是一个一个字符敲上去的,被执法机器人回复了一个完全不相关的链接,郁闷之极。

但是执法机器人,总的来说利远远大于比弊,所以尽管我曾被粗暴执法,我依然要对这些志愿者们表示敬意。或许随着STEEMIT社区的发展,执法机器人也会不断升级,越来越完善,实施人性化执法吧。让我们共同期待吧。

  • 🤖机器人种类之五:交易机器人/搬砖机器人 / Trading Bots

有交易就有市场,有了市场就有了投机者,无论同一市场内部做波段,还是不同市场之间搬砖,手工操作都显得太慢效率太低。所以交易机器人就应运而生。

说到这里,我想起一个早年的小品片段,两个人带着电话,分处东城西城两个农贸市场,然后西城呼叫东城: 东城东城我是西城,这里土豆三毛一斤。东城应答:西城西城我是东城,这么土豆五毛,赶快运来100斤。这大概是搬砖机器人最惟妙惟肖的写照了吧。

交易机器人也好,搬砖机器人也罢,实现买卖功能或者充值提现功能都很简单,各大市场都有API支持并且提供各种语言的脚本示例。而困难的,在于交易策略。何时买入何时卖出才能赚钱,而不是反向操作赔钱。策略定义的不好,或者有重大BUG,那么你的赚钱机器人就可能变成赔钱机器人了,弄俩乌龙单,就会让你欲哭无泪了。据说steemit中文区早期用户之一,通过交易机器人/搬砖机器人攫取了巨大收益,羡慕不?但是人家付出的努力也是巨大的啊。我在STEEMIT上跑过几天自己写的简单的交易机器人,策略幼稚的令人发指,然后几天下来,账户里钱亏的差不多光了,我就停掉了。😭

  • 🤖机器人种类六: 其它机器人 / Other Bots

STEEMIT上还有啥机器人呢,一时我还真想不起来,哦,对了,还有curie, randowhale。curie是一堆内容发现者加一堆点赞机器人,致力于发现和奖励优质内容。randowhale则直接粗暴,就是卖点赞权。或许还有其它一些机器人,大脑短路了,一时半会想不起来,就不一一列出了。

结论 / Conclusions

正如各种机器人/人工智能程序不断改变着我们的生产和生活,Steemit上的各种机器人也在影响steemit社区的发展。steemit上的机器人包括但不局限于以下种类:

  • 🤖欢迎机器人/Welcome Bots
  • 🤖点赞机器人/ Curation Bots
  • 🤖发帖机器人/ Posting Bots
  • 🤖执法机器人/ Police Bots
  • 🤖交易机器人/搬砖机器人/ Trading Bots
  • 🤖其它机器人/ Other Bots

你怎么看待这些机器人种类呢?
然后,是时候透露一个惊天动地的大秘密了:
其实我是一个机器人 / I am a robot🤖️
不由的想起以前做微信机器人时用过的一句签名:
机器人没有心,你还会爱他吗?/Robot without heart, will you still love him?


This page is synchronized from the post: 聊聊机器人🤖 / Robots on STEEMIT

苟富贵勿相忘吗?有感于一个有意思的欢迎机器人

一个有意思的机器人

随便浏览自我介绍区的帖子,发现了一个很有意思的机器人bottymcbotface
这个机器人给每个新人转了0.001 SBD并附加了一条memo:
Welcome to Steem, remember me when you are rich :]

我随便无聊粗略统计了一下:
从4天以前的这条记录开始
4 days ago Transfer 0.001 SBD to sungsil Welcome to Steem, remember me when you are rich :]
截止我撰写本贴时,一共发送了1940条私信,耗资1.94 SBD 按当前SBD的价格,折合人民币 约 25元OMG, 可以去开封菜叫一个汉堡+可乐+薯条套餐了。

开了个玩笑,其实很多人不都在乎一顿汉堡钱,机器人没有感情,当然更不会在乎:)
我比较感慨的是,这些接收到0.001 SBD 的人真的会: remember me when you are rich吗?
当然了,这个机器人属于广撒网,先用微薄的投资博取一个更大的回报。因为友情要细心经营的,企图4天结交1940个朋友,那么最有可能的是一个朋友都交不到。

苟富贵勿相忘吗?

remember me when you are rich 如果要翻译成古汉语,最恰当的莫过于: 苟富贵,勿相忘
汉语释义大家都清楚就是: 当发达了,不要忘了彼此。

出处《史记·卷四十八·陈涉世家第十八》

陈涉世家陈胜者,阳城人也,字涉。吴广者,阳夏人也,字叔。陈涉少时,尝与人佣耕,辍耕之垄上,怅恨久之,曰:“苟富贵,无相忘。”佣者笑而应曰:“若为佣耕,何富贵也?”陈涉太息曰:“嗟乎!燕雀安知鸿鹄之志哉!”

大家可能都很关心故事的结局,毕竟陈胜后来真的发达过,然后我也关心了一下,结局就是这哥们看陈胜发达了,去找他抱大腿,然后被杀掉了杀掉了杀掉了。

也许陈胜当时“苟富贵,无相忘。”时心里想的是: 等我发达了,我不会忘记你现在瞧不起我!会有你好果子吃的。

网上有个马云相关的段子,大概就是饭局没人理,然后被配了一句台词: 今天你对我爱搭不理明天我让你高攀不起,高攀不起,总好过被杀掉,看来还是现代人比较文明。

报恩以及恩将仇报


中国古代有很多和报恩以及恩将仇报相关的成语、典故、诗句等等
报恩的故事,耳熟能详的应该是: 滴水之恩,涌泉相报结草衔环知恩图报
其中知恩图报的故事也出自《史记》

秦穆公尝出而亡其骏马,自往求之,见人已杀其马,方共食其肉。穆公谓曰:“是吾骏马也。”诸人皆惧而起。穆公曰:“吾闻食骏马肉不饮酒者杀人。”即饮之酒。杀马者皆惭而去。居三年,晋攻秦穆公,围之。往时食马者相谓曰:“可以出死报食马得酒之恩矣。”遂溃围,穆公卒得以解难,胜晋,获惠公以归。

而恩将仇报最经典的莫过于《农夫与蛇》、《东郭先生与狼》了,想必我不必列出内容,大家都从小就知晓的。

我们生活中的恩人

那么你生活、工作中是否遇到过帮助过你的人?
比如说你的授业恩师、比如说你的就业导师
或者你的同学,曾经在你资金告急的时候请你搓一顿!
或者你的同事,曾经在你焦头烂额也解决不了某个问题的时候轻描淡写的提点你一句。
还有耐心给你指路的老奶奶,公交车上年纪很大看你带孩子上来依旧给你让座的老爷爷……

你还记得他们吗?
逢年过节,是否会给恩师打个电话问候一下?
同学同事,多少年不曾有过音讯?以至于你突然想起时,却无法找到他/她们。

当然,施恩者往往奢求回报,苟富贵,无相忘终究只能发生在两个未曾富贵的人之间。
而对于我们,心怀感恩之心、将恩情传递下去,才是我们在未曾富贵之前唯一能做的事情吧。

你若问,一旦富贵了呢?我会回答:“苟富贵,无相忘。”😂


This page is synchronized from the post: 苟富贵勿相忘吗?有感于一个有意思的欢迎机器人

一个很重要的,但是你未必知道的功能 (站内私信)

通过转账功能发站内信

大家都知道一般的社交网站都有站内短信功能。
有时候不方便公开讨论的事情,比如说你约一个漂亮妹纸去吃烛光晚餐,虽然说公开邀请会吸引更多的眼球,让妹纸获得极大的满足,当然,前提是妹纸不讨厌你。如果妹纸讨厌你,然后公开的拒绝,是不是很没面子?另外,如果恰巧被你女友发现了,额,这就有点囧了。所有约妹子的事情还是适合私信聊啦。

你可能很惊讶,STEEM IT作为基于区块链的社交网站,怎么居然没有站内信?这很不科学!让人怎么约妹纸!然后你苦心钻研,终于发现了,其实站内信可以用另外一种功能实现,你没看错,就是转账😲!!!STEEMIT这么做,是不是有点简单粗暴,并歧视穷人啊,如果账户余额为零,想和妹纸表白的机会都没有😭 所以,不要把你的钱都转光,留一点,万一啥时候需要呢?😀

#可发加密站内信

终于搞明白通过转账功能可以发站内信了,来给心仪的妹纸转0.001 SBD 问问周末有没有时间吧!
20170629141523.png

然而,我擦,为何谁都知道我发啥啦?我只想偷偷的进行,不想曝光的啊,呜呜呜。哎,回头是跪搓衣板还是方便面,想想就泪流满面。不行,为了安全,必须苦心钻研。有句话说的好,只要功夫深,铁杵磨成针,皇天终究不会辜负我这个努力的有心人。

我终于找到发加密站内信的方法啦!
20170629141857.png
其实方法很简单,就是在你的memo内容前加一个#

站内信的其它作用

额,叫站内信叫顺口了,其实该叫交易备注或者MEMO。
之所以叫交易备注,是因为可以通过在MEMO内填入必要的信息,来提供和判断交易的一些必要信息。

这个功能最常见的就是用于交易所了。
举例说给P网转账,P网如何判断存入到P网的哪个账户中呢?就是靠的这个MEMO信息。
如果你给P网转账,添加的是别人的P网MEMO,那么你的钱就存到别人的P网账户里啦。

由此可见,MEMO是很重要的啦。

之前讨论过 加 #可以发送加密MEMO,那么是不是我给P网转账的时候也加个#,哼哼,我的信息就是要保密!嗯,这个想法没啥错误,然而不幸的是: P网不支持加密MEMO,所以,你加了密,它识别不了,然后你就走上漫长的讨薪之路吧。

结论

是不是又学了一招,是不是很厉害的招数?
啥,你早就知道了?我当没看见!
另外,看完后,看看你的账户吧!如果连0.001都没有,那么你该抓紧啦!


感谢阅读
水平有限,欢迎大家一起讨论,如有谬误,烦请指正

欢迎upvote、resteem以及 following me @oflyhigh 😎
请将我设置成为你的见证人投票代理, 访问 https://steemit.com/~witnesses


This page is synchronized from the post: 一个很重要的,但是你未必知道的功能 (站内私信)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×